3 The definition of CFormPkg's member function
5 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "VfrFormPkg.h"
15 * The definition of CFormPkg's member function
18 SPendingAssign::SPendingAssign (
34 mKey
= new CHAR8
[strlen (Key
) + 1];
41 mMsg
= new CHAR8
[strlen (Msg
) + 1];
48 SPendingAssign::~SPendingAssign (
65 SPendingAssign::SetAddrAndLen (
75 SPendingAssign::AssignValue (
80 memmove (mAddr
, Addr
, (mLen
< Len
? mLen
: Len
));
85 SPendingAssign::GetKey (
102 mBufferNodeQueueHead
= NULL
;
103 mBufferNodeQueueTail
= NULL
;
104 mCurrBufferNode
= NULL
;
105 mReadBufferNode
= NULL
;
106 mReadBufferOffset
= 0;
107 PendingAssignList
= NULL
;
109 Node
= new SBufferNode
;
113 BufferStart
= new CHAR8
[BufferSize
];
114 if (BufferStart
== NULL
) {
118 BufferEnd
= BufferStart
+ BufferSize
;
120 memset (BufferStart
, 0, BufferSize
);
121 Node
->mBufferStart
= BufferStart
;
122 Node
->mBufferEnd
= BufferEnd
;
123 Node
->mBufferFree
= BufferStart
;
126 mBufferSize
= BufferSize
;
127 mBufferNodeQueueHead
= Node
;
128 mBufferNodeQueueTail
= Node
;
129 mCurrBufferNode
= Node
;
132 CFormPkg::~CFormPkg ()
135 SPendingAssign
*pPNode
;
137 while (mBufferNodeQueueHead
!= NULL
) {
138 pBNode
= mBufferNodeQueueHead
;
139 mBufferNodeQueueHead
= mBufferNodeQueueHead
->mNext
;
140 if (pBNode
->mBufferStart
!= NULL
) {
141 delete[] pBNode
->mBufferStart
;
145 mBufferNodeQueueTail
= NULL
;
146 mCurrBufferNode
= NULL
;
148 while (PendingAssignList
!= NULL
) {
149 pPNode
= PendingAssignList
;
150 PendingAssignList
= PendingAssignList
->mNext
;
153 PendingAssignList
= NULL
;
157 CFormPkg::CreateNewNode (
163 Node
= new SBufferNode
;
168 Node
->mBufferStart
= new CHAR8
[mBufferSize
];
169 if (Node
->mBufferStart
== NULL
) {
173 memset (Node
->mBufferStart
, 0, mBufferSize
);
174 Node
->mBufferEnd
= Node
->mBufferStart
+ mBufferSize
;
175 Node
->mBufferFree
= Node
->mBufferStart
;
183 CFormPkg::IfrBinBufferGet (
187 CHAR8
*BinBuffer
= NULL
;
188 SBufferNode
*Node
= NULL
;
190 if ((Len
== 0) || (Len
> mBufferSize
)) {
194 if ((mCurrBufferNode
->mBufferFree
+ Len
) <= mCurrBufferNode
->mBufferEnd
) {
195 BinBuffer
= mCurrBufferNode
->mBufferFree
;
196 mCurrBufferNode
->mBufferFree
+= Len
;
198 Node
= CreateNewNode ();
203 if (mBufferNodeQueueTail
== NULL
) {
204 mBufferNodeQueueHead
= mBufferNodeQueueTail
= Node
;
206 mBufferNodeQueueTail
->mNext
= Node
;
207 mBufferNodeQueueTail
= Node
;
209 mCurrBufferNode
= Node
;
214 BinBuffer
= mCurrBufferNode
->mBufferFree
;
215 mCurrBufferNode
->mBufferFree
+= Len
;
225 CFormPkg::GetPkgLength (
237 mReadBufferNode
= mBufferNodeQueueHead
;
238 mReadBufferOffset
= 0;
246 mReadBufferNode
= NULL
;
247 mReadBufferOffset
= 0;
258 if ((Size
== 0) || (Buffer
== NULL
)) {
262 if (mReadBufferNode
== NULL
) {
266 for (Index
= 0; Index
< Size
; Index
++) {
267 if ((mReadBufferNode
->mBufferStart
+ mReadBufferOffset
) < mReadBufferNode
->mBufferFree
) {
268 Buffer
[Index
] = mReadBufferNode
->mBufferStart
[mReadBufferOffset
++];
270 if ((mReadBufferNode
= mReadBufferNode
->mNext
) == NULL
) {
273 mReadBufferOffset
= 0;
283 CFormPkg::BuildPkgHdr (
284 OUT EFI_HII_PACKAGE_HEADER
**PkgHdr
287 if (PkgHdr
== NULL
) {
288 return VFR_RETURN_FATAL_ERROR
;
291 if (((*PkgHdr
) = new EFI_HII_PACKAGE_HEADER
) == NULL
) {
292 return VFR_RETURN_OUT_FOR_RESOURCES
;
295 (*PkgHdr
)->Type
= EFI_HII_PACKAGE_FORM
;
296 (*PkgHdr
)->Length
= mPkgLength
+ sizeof (EFI_HII_PACKAGE_HEADER
);
298 return VFR_RETURN_SUCCESS
;
303 OUT PACKAGE_DATA
&TBuffer
311 if (TBuffer
.Buffer
!= NULL
) {
312 delete TBuffer
.Buffer
;
315 TBuffer
.Size
= mPkgLength
;
316 TBuffer
.Buffer
= NULL
;
317 if (TBuffer
.Size
!= 0) {
318 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
320 return VFR_RETURN_SUCCESS
;
323 Temp
= TBuffer
.Buffer
;
325 while ((Size
= Read (Buffer
, 1024)) != 0) {
326 memcpy (Temp
, Buffer
, Size
);
330 return VFR_RETURN_SUCCESS
;
337 IN PACKAGE_DATA
*PkgData
340 EFI_VFR_RETURN_CODE Ret
;
343 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
345 if (Output
== NULL
) {
346 return VFR_RETURN_FATAL_ERROR
;
349 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
352 fwrite (PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
), 1, Output
);
355 if (PkgData
== NULL
) {
357 while ((Size
= Read (Buffer
, 1024)) != 0) {
358 fwrite (Buffer
, Size
, 1, Output
);
362 fwrite (PkgData
->Buffer
, PkgData
->Size
, 1, Output
);
365 return VFR_RETURN_SUCCESS
;
369 CFormPkg::_WRITE_PKG_LINE (
372 IN CONST CHAR8
*LineHeader
,
379 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
383 for (Index
= 0; Index
< BlkSize
; Index
++) {
384 if ((Index
% LineBytes
) == 0) {
385 fprintf (pFile
, "\n%s", LineHeader
);
387 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
392 CFormPkg::_WRITE_PKG_END (
395 IN CONST CHAR8
*LineHeader
,
402 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
406 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
407 if ((Index
% LineBytes
) == 0) {
408 fprintf (pFile
, "\n%s", LineHeader
);
410 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
413 if ((Index
% LineBytes
) == 0) {
414 fprintf (pFile
, "\n%s", LineHeader
);
416 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
419 #define BYTES_PRE_LINE 0x10
420 UINT32 gAdjustOpcodeOffset
= 0;
421 BOOLEAN gNeedAdjustOpcode
= FALSE
;
422 UINT32 gAdjustOpcodeLen
= 0;
428 IN PACKAGE_DATA
*PkgData
431 EFI_VFR_RETURN_CODE Ret
;
432 CHAR8 Buffer
[BYTES_PRE_LINE
* 8];
433 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
434 UINT32 PkgLength
= 0;
437 if ((BaseName
== NULL
) || (pFile
== NULL
)) {
438 return VFR_RETURN_FATAL_ERROR
;
441 fprintf (pFile
, "\nunsigned char %sBin[] = {\n", BaseName
);
443 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
448 fprintf (pFile
, " // ARRAY LENGTH\n");
449 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
);
450 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
452 fprintf (pFile
, "\n\n // PACKAGE HEADER\n");
453 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
454 PkgLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
456 fprintf (pFile
, "\n\n // PACKAGE DATA\n");
458 if (PkgData
== NULL
) {
460 while ((ReadSize
= Read ((CHAR8
*)Buffer
, BYTES_PRE_LINE
* 8)) != 0) {
461 PkgLength
+= ReadSize
;
462 if (PkgLength
< PkgHdr
->Length
) {
463 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
465 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
470 if (PkgData
->Size
% BYTES_PRE_LINE
!= 0) {
471 PkgLength
= PkgData
->Size
- (PkgData
->Size
% BYTES_PRE_LINE
);
472 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
473 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, PkgData
->Size
% BYTES_PRE_LINE
);
475 PkgLength
= PkgData
->Size
- BYTES_PRE_LINE
;
476 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
477 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, BYTES_PRE_LINE
);
482 fprintf (pFile
, "\n};\n");
484 return VFR_RETURN_SUCCESS
;
488 CFormPkg::AssignPending (
496 SPendingAssign
*pNew
;
498 pNew
= new SPendingAssign (Key
, ValAddr
, ValLen
, LineNo
, Msg
);
500 return VFR_RETURN_OUT_FOR_RESOURCES
;
503 pNew
->mNext
= PendingAssignList
;
504 PendingAssignList
= pNew
;
505 return VFR_RETURN_SUCCESS
;
509 CFormPkg::DoPendingAssign (
515 SPendingAssign
*pNode
;
517 if ((Key
== NULL
) || (ValAddr
== NULL
)) {
521 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
522 if (strcmp (pNode
->mKey
, Key
) == 0) {
523 pNode
->AssignValue (ValAddr
, ValLen
);
529 CFormPkg::HavePendingUnassigned (
533 SPendingAssign
*pNode
;
535 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
536 if (pNode
->mFlag
== PENDING
) {
545 CFormPkg::PendingAssignPrintAll (
549 SPendingAssign
*pNode
;
551 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
552 if (pNode
->mFlag
== PENDING
) {
553 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", pNode
->mMsg
);
559 CFormPkg::GetBinBufferNodeForAddr (
560 IN CHAR8
*BinBuffAddr
563 SBufferNode
*TmpNode
;
565 TmpNode
= mBufferNodeQueueHead
;
567 while (TmpNode
!= NULL
) {
568 if (TmpNode
->mBufferStart
<= BinBuffAddr
&& TmpNode
->mBufferFree
>= BinBuffAddr
) {
572 TmpNode
= TmpNode
->mNext
;
579 CFormPkg::GetNodeBefore(
580 IN SBufferNode
*CurrentNode
583 SBufferNode
*FirstNode
= mBufferNodeQueueHead
;
584 SBufferNode
*LastNode
= mBufferNodeQueueHead
;
586 while (FirstNode
!= NULL
) {
587 if (FirstNode
== CurrentNode
) {
591 LastNode
= FirstNode
;
592 FirstNode
= FirstNode
->mNext
;
595 if (FirstNode
== NULL
) {
603 CFormPkg::InsertNodeBefore(
604 IN SBufferNode
*CurrentNode
,
605 IN SBufferNode
*NewNode
608 SBufferNode
*LastNode
= GetNodeBefore (CurrentNode
);
610 if (LastNode
== NULL
) {
611 return VFR_RETURN_MISMATCHED
;
614 NewNode
->mNext
= LastNode
->mNext
;
615 LastNode
->mNext
= NewNode
;
617 return VFR_RETURN_SUCCESS
;
621 CFormPkg::GetBufAddrBaseOnOffset (
625 SBufferNode
*TmpNode
;
627 UINT32 CurrentBufLen
;
631 for (TmpNode
= mBufferNodeQueueHead
; TmpNode
!= NULL
; TmpNode
= TmpNode
->mNext
) {
632 CurrentBufLen
= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
633 if (Offset
>= TotalBufLen
&& Offset
< TotalBufLen
+ CurrentBufLen
) {
634 return TmpNode
->mBufferStart
+ (Offset
- TotalBufLen
);
637 TotalBufLen
+= CurrentBufLen
;
644 CFormPkg::AdjustDynamicInsertOpcode (
645 IN CHAR8
*InserPositionAddr
,
646 IN CHAR8
*InsertOpcodeAddr
,
647 IN BOOLEAN CreateOpcodeAfterParsingVfr
650 SBufferNode
*InserPositionNode
;
651 SBufferNode
*InsertOpcodeNode
;
652 SBufferNode
*NewRestoreNodeBegin
;
653 SBufferNode
*NewRestoreNodeEnd
;
654 SBufferNode
*NewLastEndNode
;
655 SBufferNode
*TmpNode
;
656 UINT32 NeedRestoreCodeLen
;
658 NewRestoreNodeEnd
= NULL
;
660 InserPositionNode
= GetBinBufferNodeForAddr(InserPositionAddr
);
661 InsertOpcodeNode
= GetBinBufferNodeForAddr(InsertOpcodeAddr
);
662 assert (InserPositionNode
!= NULL
);
663 assert (InsertOpcodeNode
!= NULL
);
665 if (InserPositionNode
== InsertOpcodeNode
) {
667 // Create New Node to save the restore opcode.
669 NeedRestoreCodeLen
= InsertOpcodeAddr
- InserPositionAddr
;
670 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
671 NewRestoreNodeBegin
= CreateNewNode ();
672 if (NewRestoreNodeBegin
== NULL
) {
673 return VFR_RETURN_OUT_FOR_RESOURCES
;
675 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
676 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
679 // Override the restore buffer data.
681 memmove (InserPositionAddr
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
682 InsertOpcodeNode
->mBufferFree
-= NeedRestoreCodeLen
;
683 memset (InsertOpcodeNode
->mBufferFree
, 0, NeedRestoreCodeLen
);
686 // Create New Node to save the restore opcode.
688 NeedRestoreCodeLen
= InserPositionNode
->mBufferFree
- InserPositionAddr
;
689 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
690 NewRestoreNodeBegin
= CreateNewNode ();
691 if (NewRestoreNodeBegin
== NULL
) {
692 return VFR_RETURN_OUT_FOR_RESOURCES
;
694 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
695 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
697 // Override the restore buffer data.
699 InserPositionNode
->mBufferFree
-= NeedRestoreCodeLen
;
701 // Link the restore data to new node.
703 NewRestoreNodeBegin
->mNext
= InserPositionNode
->mNext
;
706 // Count the Adjust opcode len.
708 TmpNode
= InserPositionNode
->mNext
;
709 while (TmpNode
!= InsertOpcodeNode
) {
710 gAdjustOpcodeLen
+= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
711 TmpNode
= TmpNode
->mNext
;
715 // Create New Node to save the last node of restore opcode.
717 NeedRestoreCodeLen
= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
718 gAdjustOpcodeLen
+= NeedRestoreCodeLen
;
719 if (NeedRestoreCodeLen
> 0) {
720 NewRestoreNodeEnd
= CreateNewNode ();
721 if (NewRestoreNodeEnd
== NULL
) {
722 return VFR_RETURN_OUT_FOR_RESOURCES
;
724 memcpy (NewRestoreNodeEnd
->mBufferFree
, InsertOpcodeNode
->mBufferStart
, NeedRestoreCodeLen
);
725 NewRestoreNodeEnd
->mBufferFree
+= NeedRestoreCodeLen
;
727 // Override the restore buffer data.
729 memmove (InsertOpcodeNode
->mBufferStart
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
730 InsertOpcodeNode
->mBufferFree
-= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
733 // Insert the last restore data node.
735 TmpNode
= GetNodeBefore (InsertOpcodeNode
);
736 assert (TmpNode
!= NULL
);
738 if (TmpNode
== InserPositionNode
) {
739 NewRestoreNodeBegin
->mNext
= NewRestoreNodeEnd
;
741 TmpNode
->mNext
= NewRestoreNodeEnd
;
744 // Connect the dynamic opcode node to the node after InserPositionNode.
746 InserPositionNode
->mNext
= InsertOpcodeNode
;
750 if (CreateOpcodeAfterParsingVfr
) {
752 // Th new opcodes were created after Parsing Vfr file,
753 // so the content in mBufferNodeQueueTail must be the new created opcodes.
754 // So connet the NewRestoreNodeBegin to the tail and update the tail node.
756 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
757 if (NewRestoreNodeEnd
!= NULL
) {
758 mBufferNodeQueueTail
= NewRestoreNodeEnd
;
760 mBufferNodeQueueTail
= NewRestoreNodeBegin
;
763 if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
> 2) {
765 // End form set opcode all in the mBufferNodeQueueTail node.
767 NewLastEndNode
= CreateNewNode ();
768 if (NewLastEndNode
== NULL
) {
769 return VFR_RETURN_OUT_FOR_RESOURCES
;
771 NewLastEndNode
->mBufferStart
[0] = 0x29;
772 NewLastEndNode
->mBufferStart
[1] = 0x02;
773 NewLastEndNode
->mBufferFree
+= 2;
775 mBufferNodeQueueTail
->mBufferFree
-= 2;
777 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
778 if (NewRestoreNodeEnd
!= NULL
) {
779 NewRestoreNodeEnd
->mNext
= NewLastEndNode
;
781 NewRestoreNodeBegin
->mNext
= NewLastEndNode
;
784 mBufferNodeQueueTail
= NewLastEndNode
;
785 } else if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
== 2) {
786 TmpNode
= GetNodeBefore(mBufferNodeQueueTail
);
787 assert (TmpNode
!= NULL
);
789 TmpNode
->mNext
= NewRestoreNodeBegin
;
790 if (NewRestoreNodeEnd
!= NULL
) {
791 NewRestoreNodeEnd
->mNext
= mBufferNodeQueueTail
;
793 NewRestoreNodeBegin
->mNext
= mBufferNodeQueueTail
;
797 mCurrBufferNode
= mBufferNodeQueueTail
;
798 return VFR_RETURN_SUCCESS
;
802 CFormPkg::DeclarePendingQuestion (
803 IN CVfrVarDataTypeDB
&lCVfrVarDataTypeDB
,
804 IN CVfrDataStorage
&lCVfrDataStorage
,
805 IN CVfrQuestionDB
&lCVfrQuestionDB
,
806 IN EFI_GUID
*LocalFormSetGuid
,
808 OUT CHAR8
**InsertOpcodeAddr
811 SPendingAssign
*pNode
;
814 CHAR8 FName
[MAX_NAME_LEN
];
817 UINT32 ShrinkSize
= 0;
818 EFI_VFR_RETURN_CODE ReturnCode
;
819 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
822 CIfrGuid
*GuidObj
= NULL
;
825 // Declare all questions as Numeric in DisableIf True
829 DIObj
.SetLineNo (LineNo
);
830 *InsertOpcodeAddr
= DIObj
.GetObjBinAddr
<CHAR8
>();
833 CIfrTrue
TObj (LineNo
);
835 // Declare Numeric qeustion for each undefined question.
836 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
837 if (pNode
->mFlag
== PENDING
) {
838 EFI_VARSTORE_INFO Info
;
839 EFI_QUESTION_ID QId
= EFI_QUESTION_ID_INVALID
;
841 // Register this question, assume it is normal question, not date or time question
843 VarStr
= pNode
->mKey
;
844 ReturnCode
= lCVfrQuestionDB
.RegisterQuestion (NULL
, VarStr
, QId
);
845 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
846 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
851 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr
, QId
);
854 // Get Question Info, framework vfr VarName == StructName
856 ReturnCode
= lCVfrVarDataTypeDB
.ExtractFieldNameAndArrary (VarStr
, FName
, ArrayIdx
);
857 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
858 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", "Var string is not the valid C variable");
864 ReturnCode
= lCVfrDataStorage
.GetVarStoreId (FName
, &Info
.mVarStoreId
);
865 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
866 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, FName
, "Error", "Var Store Type is not defined");
869 VarStoreType
= lCVfrDataStorage
.GetVarStoreType (Info
.mVarStoreId
);
871 if (*VarStr
== '\0' && ArrayIdx
!= INVALID_ARRAY_INDEX
) {
872 ReturnCode
= lCVfrDataStorage
.GetNameVarStoreInfo (&Info
, ArrayIdx
);
874 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
875 ReturnCode
= lCVfrDataStorage
.GetEfiVarStoreInfo (&Info
);
876 } else if (VarStoreType
== EFI_VFR_VARSTORE_BUFFER
|| VarStoreType
== EFI_VFR_VARSTORE_BUFFER_BITS
) {
877 VarStr
= pNode
->mKey
;
878 //convert VarStr with store name to VarStr with structure name
879 ReturnCode
= lCVfrDataStorage
.GetBufferVarStoreDataTypeName (Info
.mVarStoreId
, &SName
);
880 if (ReturnCode
== VFR_RETURN_SUCCESS
) {
881 NewStr
= new CHAR8
[strlen (VarStr
) + strlen (SName
) + 1];
883 strcpy (NewStr
, SName
);
884 strcat (NewStr
, VarStr
+ strlen (FName
));
885 ReturnCode
= lCVfrVarDataTypeDB
.GetDataFieldInfo (NewStr
, Info
.mInfo
.mVarOffset
, Info
.mVarType
, Info
.mVarTotalSize
, Info
.mIsBitVar
);
889 ReturnCode
= VFR_RETURN_UNSUPPORTED
;
892 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
893 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
897 // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.
899 if (Info
.mIsBitVar
) {
900 GuidObj
= new CIfrGuid(0);
901 GuidObj
->SetGuid (&gEdkiiIfrBitVarGuid
);
902 GuidObj
->SetLineNo(LineNo
);
906 CNObj
.SetLineNo (LineNo
);
907 CNObj
.SetPrompt (0x0);
909 CNObj
.SetQuestionId (QId
);
910 CNObj
.SetVarStoreInfo (&Info
);
913 // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.
915 if (Info
.mIsBitVar
) {
916 MaxValue
= (1 << Info
.mVarTotalSize
) -1;
917 CNObj
.SetMinMaxStepData ((UINT32
) 0, MaxValue
, (UINT32
) 0);
919 LFlags
= (EDKII_IFR_NUMERIC_SIZE_BIT
& Info
.mVarTotalSize
);
920 CNObj
.SetFlagsForBitField (0, LFlags
);
923 // Numeric doesn't support BOOLEAN data type.
924 // BOOLEAN type has the same data size to UINT8.
926 if (Info
.mVarType
== EFI_IFR_TYPE_BOOLEAN
) {
927 Info
.mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
929 CNObj
.SetFlags (0, Info
.mVarType
);
931 // Use maximum value not to limit the valid value for the undefined question.
933 switch (Info
.mVarType
) {
934 case EFI_IFR_TYPE_NUM_SIZE_64
:
935 CNObj
.SetMinMaxStepData ((UINT64
) 0, (UINT64
) -1 , (UINT64
) 0);
938 case EFI_IFR_TYPE_NUM_SIZE_32
:
939 CNObj
.SetMinMaxStepData ((UINT32
) 0, (UINT32
) -1 , (UINT32
) 0);
942 case EFI_IFR_TYPE_NUM_SIZE_16
:
943 CNObj
.SetMinMaxStepData ((UINT16
) 0, (UINT16
) -1 , (UINT16
) 0);
946 case EFI_IFR_TYPE_NUM_SIZE_8
:
947 CNObj
.SetMinMaxStepData ((UINT8
) 0, (UINT8
) -1 , (UINT8
) 0);
954 CNObj
.ShrinkBinSize (ShrinkSize
);
957 // For undefined Efi VarStore type question
958 // Append the extended guided opcode to contain VarName
960 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
961 CIfrVarEqName
CVNObj (QId
, Info
.mInfo
.mVarName
);
962 CVNObj
.SetLineNo (LineNo
);
969 CEObj
.SetLineNo (LineNo
);
971 // End for Guided opcode
973 if (GuidObj
!= NULL
) {
975 CEObjGuid
.SetLineNo (LineNo
);
976 GuidObj
->SetScope(1);
987 SEObj
.SetLineNo (LineNo
);
989 return VFR_RETURN_SUCCESS
;
994 SIfrRecord::SIfrRecord (
1000 mLineNo
= 0xFFFFFFFF;
1001 mOffset
= 0xFFFFFFFF;
1005 SIfrRecord::~SIfrRecord (
1009 if (mIfrBinBuf
!= NULL
) {
1010 //delete mIfrBinBuf;
1013 mLineNo
= 0xFFFFFFFF;
1014 mOffset
= 0xFFFFFFFF;
1019 CIfrRecordInfoDB::CIfrRecordInfoDB (
1024 mRecordCount
= EFI_IFR_RECORDINFO_IDX_START
;
1025 mIfrRecordListHead
= NULL
;
1026 mIfrRecordListTail
= NULL
;
1027 mAllDefaultTypeCount
= 0;
1028 for (UINT8 i
= 0; i
< EFI_HII_MAX_SUPPORT_DEFAULT_TYPE
; i
++) {
1029 mAllDefaultIdArray
[i
] = 0xffff;
1033 CIfrRecordInfoDB::~CIfrRecordInfoDB (
1039 while (mIfrRecordListHead
!= NULL
) {
1040 pNode
= mIfrRecordListHead
;
1041 mIfrRecordListHead
= mIfrRecordListHead
->mNext
;
1047 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1052 SIfrRecord
*pNode
= NULL
;
1054 if (RecordIdx
== EFI_IFR_RECORDINFO_IDX_INVALUD
) {
1058 for (Idx
= (EFI_IFR_RECORDINFO_IDX_START
+ 1), pNode
= mIfrRecordListHead
;
1059 (Idx
!= RecordIdx
) && (pNode
!= NULL
);
1060 Idx
++, pNode
= pNode
->mNext
)
1067 CIfrRecordInfoDB::IfrRecordRegister (
1069 IN CHAR8
*IfrBinBuf
,
1076 if (mSwitch
== FALSE
) {
1077 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1080 if ((pNew
= new SIfrRecord
) == NULL
) {
1081 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1084 if (mIfrRecordListHead
== NULL
) {
1085 mIfrRecordListHead
= pNew
;
1086 mIfrRecordListTail
= pNew
;
1088 mIfrRecordListTail
->mNext
= pNew
;
1089 mIfrRecordListTail
= pNew
;
1093 return mRecordCount
;
1097 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1098 IN UINT32 RecordIdx
,
1108 if ((pNode
= GetRecordInfoFromIdx (RecordIdx
)) == NULL
) {
1114 // Line number is not specified explicitly, try to use line number of previous opcode
1116 Prev
= GetRecordInfoFromIdx (RecordIdx
- 1);
1118 LineNo
= Prev
->mLineNo
;
1122 pNode
->mLineNo
= LineNo
;
1123 pNode
->mOffset
= Offset
;
1124 pNode
->mBinBufLen
= BinBufLen
;
1125 pNode
->mIfrBinBuf
= BinBuf
;
1130 CIfrRecordInfoDB::IfrRecordOutput (
1131 OUT PACKAGE_DATA
&TBuffer
1137 if (TBuffer
.Buffer
!= NULL
) {
1138 delete[] TBuffer
.Buffer
;
1142 TBuffer
.Buffer
= NULL
;
1145 if (mSwitch
== FALSE
) {
1149 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1150 TBuffer
.Size
+= pNode
->mBinBufLen
;
1153 if (TBuffer
.Size
!= 0) {
1154 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
1159 Temp
= TBuffer
.Buffer
;
1161 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1162 if (pNode
->mIfrBinBuf
!= NULL
) {
1163 memcpy (Temp
, pNode
->mIfrBinBuf
, pNode
->mBinBufLen
);
1164 Temp
+= pNode
->mBinBufLen
;
1172 CIfrRecordInfoDB::IfrRecordOutput (
1181 if (mSwitch
== FALSE
) {
1191 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1192 if (pNode
->mLineNo
== LineNo
|| LineNo
== 0) {
1193 fprintf (File
, ">%08X: ", pNode
->mOffset
);
1194 TotalSize
+= pNode
->mBinBufLen
;
1195 if (pNode
->mIfrBinBuf
!= NULL
) {
1196 for (Index
= 0; Index
< pNode
->mBinBufLen
; Index
++) {
1197 fprintf (File
, "%02X ", (UINT8
)(pNode
->mIfrBinBuf
[Index
]));
1200 fprintf (File
, "\n");
1205 fprintf (File
, "\nTotal Size of all record is 0x%08X\n", TotalSize
);
1210 // for framework vfr file
1211 // adjust opcode sequence for uefi IFR format
1212 // adjust inconsistent and varstore into the right position.
1215 CIfrRecordInfoDB::CheckQuestionOpCode (
1220 case EFI_IFR_CHECKBOX_OP
:
1221 case EFI_IFR_NUMERIC_OP
:
1222 case EFI_IFR_PASSWORD_OP
:
1223 case EFI_IFR_ONE_OF_OP
:
1224 case EFI_IFR_ACTION_OP
:
1225 case EFI_IFR_STRING_OP
:
1226 case EFI_IFR_DATE_OP
:
1227 case EFI_IFR_TIME_OP
:
1228 case EFI_IFR_ORDERED_LIST_OP
:
1229 case EFI_IFR_REF_OP
:
1237 CIfrRecordInfoDB::CheckIdOpCode (
1242 case EFI_IFR_EQ_ID_VAL_OP
:
1243 case EFI_IFR_EQ_ID_ID_OP
:
1244 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1245 case EFI_IFR_QUESTION_REF1_OP
:
1253 CIfrRecordInfoDB::GetOpcodeQuestionId (
1254 IN EFI_IFR_OP_HEADER
*OpHead
1257 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1259 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (OpHead
+ 1);
1261 return QuestionHead
->QuestionId
;
1265 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1269 SIfrRecord
*pNode
= NULL
;
1271 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1272 if (pNode
->mOffset
== Offset
) {
1281 Add just the op code position.
1283 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1284 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1288 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1292 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1294 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1295 so new records are appennded to the end of OriginalIfrRecordListTail.
1299 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1303 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1306 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1310 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1311 IN BOOLEAN CreateOpcodeAfterParsingVfr
1314 UINT32 OpcodeOffset
;
1315 SIfrRecord
*pNode
, *pPreNode
;
1316 SIfrRecord
*pAdjustNode
, *pNodeBeforeAdjust
;
1317 SIfrRecord
*pNodeBeforeDynamic
;
1321 pNodeBeforeDynamic
= NULL
;
1325 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1326 // and the node before pDynamicOpcodeNode.
1328 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1329 if (OpcodeOffset
== gAdjustOpcodeOffset
) {
1330 pAdjustNode
= pNode
;
1331 pNodeBeforeAdjust
= pPreNode
;
1332 } else if (OpcodeOffset
== gAdjustOpcodeOffset
+ gAdjustOpcodeLen
) {
1333 pNodeBeforeDynamic
= pPreNode
;
1335 if (pNode
->mNext
!= NULL
) {
1338 OpcodeOffset
+= pNode
->mBinBufLen
;
1342 // Check the nodes whether exist.
1344 if (pNodeBeforeDynamic
== NULL
|| pAdjustNode
== NULL
|| pNodeBeforeAdjust
== NULL
) {
1349 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1351 pNodeBeforeAdjust
->mNext
= pNodeBeforeDynamic
->mNext
;
1352 if (CreateOpcodeAfterParsingVfr
) {
1354 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1356 mIfrRecordListTail
->mNext
= pAdjustNode
;
1357 mIfrRecordListTail
= pNodeBeforeDynamic
;
1358 mIfrRecordListTail
->mNext
= NULL
;
1361 //pPreNode is the end of pDynamicNode(Case1).
1363 pPreNode
->mNext
= pAdjustNode
;
1364 pNodeBeforeDynamic
->mNext
= mIfrRecordListTail
;
1371 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1373 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1377 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1378 IN BOOLEAN CreateOpcodeAfterParsingVfr
1381 SIfrRecord
*pRecord
;
1384 // Base on the original offset info to update the record list.
1386 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr
)) {
1387 gCVfrErrorHandle
.PrintMsg (0, (CHAR8
*)"Error", (CHAR8
*)"Can not find the adjust offset in the record.");
1391 // Base on the opcode binary length to recalculate the offset for each opcode.
1393 IfrAdjustOffsetForRecord();
1396 // Base on the offset to find the binary address.
1398 pRecord
= GetRecordInfoFromOffset(gAdjustOpcodeOffset
);
1399 while (pRecord
!= NULL
) {
1400 pRecord
->mIfrBinBuf
= gCFormPkg
.GetBufAddrBaseOnOffset(pRecord
->mOffset
);
1401 pRecord
= pRecord
->mNext
;
1407 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1411 UINT32 OpcodeOffset
;
1415 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1416 pNode
->mOffset
= OpcodeOffset
;
1417 OpcodeOffset
+= pNode
->mBinBufLen
;
1422 CIfrRecordInfoDB::IfrRecordAdjust (
1426 SIfrRecord
*pNode
, *preNode
;
1427 SIfrRecord
*uNode
, *tNode
;
1428 EFI_IFR_OP_HEADER
*OpHead
, *tOpHead
;
1429 EFI_QUESTION_ID QuestionId
;
1431 UINT32 QuestionScope
;
1432 CHAR8 ErrorMsg
[MAX_STRING_LEN
] = {0, };
1433 EFI_VFR_RETURN_CODE Status
;
1436 // Init local variable
1438 Status
= VFR_RETURN_SUCCESS
;
1439 pNode
= mIfrRecordListHead
;
1442 while (pNode
!= NULL
) {
1443 OpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1446 // make sure the inconsistent opcode in question scope
1448 if (QuestionScope
> 0) {
1449 QuestionScope
+= OpHead
->Scope
;
1450 if (OpHead
->OpCode
== EFI_IFR_END_OP
) {
1455 if (CheckQuestionOpCode (OpHead
->OpCode
)) {
1459 // for the inconsistent opcode not in question scope, adjust it
1461 if (OpHead
->OpCode
== EFI_IFR_INCONSISTENT_IF_OP
&& QuestionScope
== 0) {
1463 // for inconsistent opcode not in question scope
1467 // Count inconsistent opcode Scope
1469 StackCount
= OpHead
->Scope
;
1470 QuestionId
= EFI_QUESTION_ID_INVALID
;
1472 while (tNode
!= NULL
&& StackCount
> 0) {
1473 tNode
= tNode
->mNext
;
1474 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mIfrBinBuf
;
1476 // Calculate Scope Number
1478 StackCount
+= tOpHead
->Scope
;
1479 if (tOpHead
->OpCode
== EFI_IFR_END_OP
) {
1483 // by IdEqual opcode to get QuestionId
1485 if (QuestionId
== EFI_QUESTION_ID_INVALID
&&
1486 CheckIdOpCode (tOpHead
->OpCode
)) {
1487 QuestionId
= *(EFI_QUESTION_ID
*) (tOpHead
+ 1);
1490 if (tNode
== NULL
|| QuestionId
== EFI_QUESTION_ID_INVALID
) {
1492 // report error; not found
1494 sprintf (ErrorMsg
, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId
);
1495 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1496 Status
= VFR_RETURN_MISMATCHED
;
1500 // extract inconsistent opcode list
1501 // pNode is Inconsistent opcode, tNode is End Opcode
1505 // insert inconsistent opcode list into the right question scope by questionid
1507 for (uNode
= mIfrRecordListHead
; uNode
!= NULL
; uNode
= uNode
->mNext
) {
1508 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mIfrBinBuf
;
1509 if (CheckQuestionOpCode (tOpHead
->OpCode
) &&
1510 (QuestionId
== GetOpcodeQuestionId (tOpHead
))) {
1515 // insert inconsistent opcode list and check LATE_CHECK flag
1517 if (uNode
!= NULL
) {
1518 if ((((EFI_IFR_QUESTION_HEADER
*)(tOpHead
+ 1))->Flags
& 0x20) != 0) {
1520 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1522 OpHead
->OpCode
= EFI_IFR_NO_SUBMIT_IF_OP
;
1526 // skip the default storage for Date and Time
1528 if ((uNode
->mNext
!= NULL
) && (*uNode
->mNext
->mIfrBinBuf
== EFI_IFR_DEFAULT_OP
)) {
1529 uNode
= uNode
->mNext
;
1532 preNode
->mNext
= tNode
->mNext
;
1533 tNode
->mNext
= uNode
->mNext
;
1534 uNode
->mNext
= pNode
;
1536 // reset pNode to head list, scan the whole list again.
1538 pNode
= mIfrRecordListHead
;
1544 // not found matched question id, report error
1546 sprintf (ErrorMsg
, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId
);
1547 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1548 Status
= VFR_RETURN_MISMATCHED
;
1551 } else if (OpHead
->OpCode
== EFI_IFR_VARSTORE_OP
||
1552 OpHead
->OpCode
== EFI_IFR_VARSTORE_EFI_OP
) {
1554 // for new added group of varstore opcode
1557 while (tNode
->mNext
!= NULL
) {
1558 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mNext
->mIfrBinBuf
;
1559 if (tOpHead
->OpCode
!= EFI_IFR_VARSTORE_OP
&&
1560 tOpHead
->OpCode
!= EFI_IFR_VARSTORE_EFI_OP
) {
1563 tNode
= tNode
->mNext
;
1566 if (tNode
->mNext
== NULL
) {
1568 // invalid IfrCode, IfrCode end by EndOpCode
1570 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", "No found End Opcode in the end");
1571 Status
= VFR_RETURN_MISMATCHED
;
1575 if (tOpHead
->OpCode
!= EFI_IFR_END_OP
) {
1577 // not new added varstore, which are not needed to be adjust.
1580 pNode
= tNode
->mNext
;
1584 // move new added varstore opcode to the position befor form opcode
1585 // varstore opcode between pNode and tNode
1589 // search form opcode from begin
1591 for (uNode
= mIfrRecordListHead
; uNode
->mNext
!= NULL
; uNode
= uNode
->mNext
) {
1592 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mNext
->mIfrBinBuf
;
1593 if (tOpHead
->OpCode
== EFI_IFR_FORM_OP
) {
1598 // Insert varstore opcode beform form opcode if form opcode is found
1600 if (uNode
->mNext
!= NULL
) {
1601 preNode
->mNext
= tNode
->mNext
;
1602 tNode
->mNext
= uNode
->mNext
;
1603 uNode
->mNext
= pNode
;
1605 // reset pNode to head list, scan the whole list again.
1607 pNode
= mIfrRecordListHead
;
1613 // not found form, continue scan IfrRecord list
1616 pNode
= tNode
->mNext
;
1625 pNode
= pNode
->mNext
;
1629 // Update Ifr Opcode Offset
1631 if (Status
== VFR_RETURN_SUCCESS
) {
1632 IfrAdjustOffsetForRecord ();
1638 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1639 given by expression, should save the default info for the Buffer VarStore.
1641 @param DefaultId The default id.
1642 @param pQuestionNode Point to the question opcode node.
1643 @param Value The default value.
1646 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1647 IN UINT16 DefaultId
,
1648 IN SIfrRecord
*pQuestionNode
,
1649 IN EFI_IFR_TYPE_VALUE Value
1652 CHAR8
*VarStoreName
= NULL
;
1653 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1654 EFI_GUID
*VarGuid
= NULL
;
1655 EFI_VARSTORE_INFO VarInfo
;
1656 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1657 EFI_IFR_OP_HEADER
*pQuestionOpHead
;
1659 pQuestionOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1660 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (pQuestionOpHead
+ 1);
1663 // Get the Var Store name and type.
1665 gCVfrDataStorage
.GetVarStoreName (QuestionHead
->VarStoreId
, &VarStoreName
);
1666 VarGuid
= gCVfrDataStorage
.GetVarStoreGuid (QuestionHead
->VarStoreId
);
1667 VarStoreType
= gCVfrDataStorage
.GetVarStoreType (QuestionHead
->VarStoreId
);
1670 // Only for Buffer storage need to save the default info in the storage.
1671 // Other type storage, just return.
1673 if (VarStoreType
!= EFI_VFR_VARSTORE_BUFFER
) {
1676 VarInfo
.mInfo
.mVarOffset
= QuestionHead
->VarStoreInfo
.VarOffset
;
1677 VarInfo
.mVarStoreId
= QuestionHead
->VarStoreId
;
1681 // Get the buffer storage info about this question.
1683 gCVfrDataStorage
.GetBufferVarStoreFieldInfo (&VarInfo
);
1688 gCVfrDefaultStore
.BufferVarStoreAltConfigAdd (
1699 Record the number and default id of all defaultstore opcode.
1703 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1708 EFI_IFR_OP_HEADER
*pOpHead
;
1709 EFI_IFR_DEFAULTSTORE
*DefaultStore
;
1711 pNode
= mIfrRecordListHead
;
1712 mAllDefaultTypeCount
= 0;
1714 while (pNode
!= NULL
) {
1715 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1717 if (pOpHead
->OpCode
== EFI_IFR_DEFAULTSTORE_OP
){
1718 DefaultStore
= (EFI_IFR_DEFAULTSTORE
*) pNode
->mIfrBinBuf
;
1719 mAllDefaultIdArray
[mAllDefaultTypeCount
++] = DefaultStore
->DefaultId
;
1721 pNode
= pNode
->mNext
;
1726 Create new default opcode record.
1728 @param Size The new default opcode size.
1729 @param DefaultId The new default id.
1730 @param Type The new default type.
1731 @param LineNo The line number of the new record.
1732 @param Value The new default value.
1736 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1738 IN UINT16 DefaultId
,
1741 IN EFI_IFR_TYPE_VALUE Value
1745 CIfrDefault2
*DObj2
;
1750 if (Type
== EFI_IFR_TYPE_OTHER
) {
1751 DObj2
= new CIfrDefault2 (Size
);
1752 DObj2
->SetDefaultId(DefaultId
);
1753 DObj2
->SetType(Type
);
1754 DObj2
->SetLineNo(LineNo
);
1755 DObj2
->SetScope (1);
1758 DObj
= new CIfrDefault (Size
);
1759 DObj
->SetDefaultId(DefaultId
);
1760 DObj
->SetType(Type
);
1761 DObj
->SetLineNo(LineNo
);
1762 DObj
->SetValue (Value
);
1768 Create new default opcode for question base on the QuestionDefaultInfo.
1770 @param pQuestionNode Point to the question opcode Node.
1771 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1775 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1776 IN SIfrRecord
*pQuestionNode
,
1777 IN QuestionDefaultRecord
*QuestionDefaultInfo
1780 EFI_IFR_OP_HEADER
*pOpHead
;
1781 EFI_IFR_DEFAULT
*Default
;
1784 SIfrRecord
*pDefaultNode
;
1791 EFI_IFR_ONE_OF_OPTION
*DefaultOptionOpcode
;
1792 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue
;
1794 CheckBoxDefaultValue
.b
= 1;
1795 pOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1801 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1803 gAdjustOpcodeOffset
= pQuestionNode
->mNext
->mOffset
;
1806 // For oneof, the default with smallest default id is given by the option flag.
1807 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1809 if (pOpHead
->OpCode
== EFI_IFR_ONE_OF_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1810 DefaultOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)QuestionDefaultInfo
->mDefaultValueRecord
->mIfrBinBuf
;
1811 DefaultSize
= QuestionDefaultInfo
->mDefaultValueRecord
->mBinBufLen
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
);
1812 DefaultSize
+= OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1813 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1814 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1815 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], DefaultOptionOpcode
->Type
, pQuestionNode
->mLineNo
, DefaultOptionOpcode
->Value
);
1817 // Save the new created default in the buffer storage.
1819 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, DefaultOptionOpcode
->Value
);
1827 // For checkbox, the default with smallest default id is given by the question flag.
1828 // And create the missing defaults with true value.
1830 if (pOpHead
-> OpCode
== EFI_IFR_CHECKBOX_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1831 DefaultSize
= OFFSET_OF (EFI_IFR_DEFAULT
, Value
) + sizeof (BOOLEAN
);
1832 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1833 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1834 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], EFI_IFR_TYPE_BOOLEAN
, pQuestionNode
->mLineNo
, CheckBoxDefaultValue
);
1836 // Save the new created default.
1838 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, CheckBoxDefaultValue
);
1846 // The default with smallest default id is given by the default opcode.
1847 // So create the missing defaults base on the value in the default opcode.
1851 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1853 pDefaultNode
= QuestionDefaultInfo
->mDefaultValueRecord
;
1854 Default
= (EFI_IFR_DEFAULT
*)pDefaultNode
->mIfrBinBuf
;
1856 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1858 gAdjustOpcodeOffset
= pDefaultNode
->mNext
->mOffset
;
1860 if (Default
->Type
== EFI_IFR_TYPE_OTHER
) {
1862 // EFI_IFR_DEFAULT_2 opcode.
1864 // Point to the first expression opcode.
1866 pSNode
= pDefaultNode
->mNext
;
1870 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1872 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& ScopeCount
!= 0) {
1873 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1874 if (pOpHead
->Scope
== 1) {
1877 if (pOpHead
->OpCode
== EFI_IFR_END_OP
) {
1881 pSNode
= pSNode
->mNext
;
1889 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1891 gAdjustOpcodeOffset
= pSNode
->mOffset
;
1893 // Create new default opcode node for missing default.
1895 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1896 OpcodeNumber
= OpcodeCount
;
1897 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1898 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pENode
->mLineNo
, Default
->Value
);
1900 // Point to the first expression opcode node.
1902 pSNode
= pDefaultNode
->mNext
;
1904 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1906 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& OpcodeNumber
-- != 0) {
1907 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1908 Obj
= new CIfrObj (pOpHead
->OpCode
, NULL
, pSNode
->mBinBufLen
, FALSE
);
1909 assert (Obj
!= NULL
);
1910 Obj
->SetLineNo (pSNode
->mLineNo
);
1911 ObjBinBuf
= Obj
->GetObjBinAddr
<CHAR8
>();
1912 memcpy (ObjBinBuf
, pSNode
->mIfrBinBuf
, (UINTN
)pSNode
->mBinBufLen
);
1914 pSNode
= pSNode
->mNext
;
1920 // EFI_IFR_DEFAULT opcode.
1922 // Create new default opcode node for missing default.
1924 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1925 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1926 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pDefaultNode
->mLineNo
, Default
->Value
);
1928 // Save the new created default in the buffer storage..
1930 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, Default
->Value
);
1937 Parse the default information in a question, get the QuestionDefaultInfo.
1939 @param pQuestionNode Point to the question record Node.
1940 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1943 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1944 IN SIfrRecord
*pQuestionNode
,
1945 OUT QuestionDefaultRecord
*QuestionDefaultInfo
1949 EFI_IFR_ONE_OF_OPTION
*OneofOptionOpcode
;
1950 EFI_IFR_OP_HEADER
*pSOpHead
;
1951 EFI_IFR_CHECKBOX
*CheckBoxOpcode
;
1952 EFI_IFR_DEFAULT
*DefaultOpcode
;
1953 BOOLEAN IsOneOfOpcode
;
1954 UINT16 SmallestDefaultId
;
1957 SmallestDefaultId
= 0xffff;
1958 IsOneOfOpcode
= FALSE
;
1960 pSNode
= pQuestionNode
;
1963 // Parse all the opcodes in the Question.
1965 while (pSNode
!= NULL
) {
1966 pSOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1968 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1969 // Scopes may be nested within other scopes.
1970 // When finishing parsing a question, the scope count must be zero.
1972 if (pSOpHead
->Scope
== 1) {
1975 if (pSOpHead
->OpCode
== EFI_IFR_END_OP
) {
1979 // Check whether finishing parsing a question.
1981 if (ScopeCount
== 0) {
1986 // Record the default information in the question.
1988 switch (pSOpHead
->OpCode
) {
1989 case EFI_IFR_ONE_OF_OP
:
1990 IsOneOfOpcode
= TRUE
;
1992 case EFI_IFR_CHECKBOX_OP
:
1994 // The default info of check box may be given by flag.
1995 // So need to check the flag of check box.
1997 CheckBoxOpcode
= (EFI_IFR_CHECKBOX
*)pSNode
->mIfrBinBuf
;
1998 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0) {
2000 // Check whether need to update the smallest default id.
2002 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2003 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2006 // Update the QuestionDefaultInfo.
2008 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2009 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2010 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2011 QuestionDefaultInfo
->mDefaultNumber
++;
2012 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2018 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0) {
2020 // Check whether need to update the smallest default id.
2022 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2023 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2026 // Update the QuestionDefaultInfo.
2028 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2029 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2030 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2031 QuestionDefaultInfo
->mDefaultNumber
++;
2032 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2039 case EFI_IFR_ONE_OF_OPTION_OP
:
2040 if (!IsOneOfOpcode
) {
2042 // Only check the option in oneof.
2046 OneofOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)pSNode
->mIfrBinBuf
;
2047 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2049 // The option is used as the standard default.
2050 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2052 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2053 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2054 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2057 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2059 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2060 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2061 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2062 QuestionDefaultInfo
->mDefaultNumber
++;
2063 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2069 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0) {
2071 // This option is used as the manufacture default.
2072 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2074 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2075 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2076 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2079 // Update the QuestionDefaultInfo.
2081 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2082 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2083 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2084 QuestionDefaultInfo
->mDefaultNumber
++;
2085 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2092 case EFI_IFR_DEFAULT_OP
:
2093 DefaultOpcode
= (EFI_IFR_DEFAULT
*) pSNode
->mIfrBinBuf
;
2095 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2097 if (SmallestDefaultId
>= DefaultOpcode
->DefaultId
) {
2098 SmallestDefaultId
= DefaultOpcode
->DefaultId
;
2099 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2100 QuestionDefaultInfo
->mIsDefaultOpcode
= TRUE
;
2103 // Update the QuestionDefaultInfo.
2105 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++){
2106 if (mAllDefaultIdArray
[i
] == ((EFI_IFR_DEFAULT
*)pSNode
->mIfrBinBuf
)->DefaultId
) {
2107 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2108 QuestionDefaultInfo
->mDefaultNumber
++;
2109 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2119 // Parse next opcode in this question.
2121 pSNode
= pSNode
->mNext
;
2126 Check or add default for question if need.
2128 This function will check the default info for question.
2129 If the question has default, but the default number < defaultstore opcode number.
2130 will do following two action :
2132 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2133 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2135 We assume that the two options can not be TRUE at same time.
2136 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2138 @param AutoDefault Add default for question if needed
2139 @param CheckDefault Check the default info, if missing default, generates an error.
2143 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2144 BOOLEAN AutoDefault
,
2145 BOOLEAN CheckDefault
2149 SIfrRecord
*pTailNode
;
2150 SIfrRecord
*pStartAdjustNode
;
2151 EFI_IFR_OP_HEADER
*pOpHead
;
2152 QuestionDefaultRecord QuestionDefaultInfo
;
2153 UINT8 MissingDefaultCount
;
2154 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
2156 pNode
= mIfrRecordListHead
;
2159 // Record the number and default id of all defaultstore opcode.
2161 IfrGetDefaultStoreInfo ();
2163 while (pNode
!= NULL
) {
2164 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
2166 // Check whether is question opcode.
2168 if (CheckQuestionOpCode (pOpHead
->OpCode
)) {
2170 // Initialize some local variables here, because they vary with question.
2171 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2173 memset (&QuestionDefaultInfo
, 0, sizeof (QuestionDefaultRecord
));
2174 pTailNode
= mIfrRecordListTail
;
2176 // Get the QuestionDefaultInfo for current question.
2178 IfrParseDefaulInfoInQuestion (pNode
, &QuestionDefaultInfo
);
2180 if (QuestionDefaultInfo
.mDefaultNumber
!= mAllDefaultTypeCount
&& QuestionDefaultInfo
.mDefaultNumber
!= 0) {
2183 // Create default for question which misses default.
2185 IfrCreateDefaultForQuestion (pNode
, &QuestionDefaultInfo
);
2188 // Adjust the buffer content.
2189 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2190 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2192 pStartAdjustNode
=GetRecordInfoFromOffset (gAdjustOpcodeOffset
);
2193 gCFormPkg
.AdjustDynamicInsertOpcode (pStartAdjustNode
->mIfrBinBuf
, pTailNode
->mNext
->mIfrBinBuf
, TRUE
);
2196 // Update the record info.
2198 IfrUpdateRecordInfoForDynamicOpcode (TRUE
);
2199 } else if (CheckDefault
) {
2201 // Generate an error for question which misses default.
2203 MissingDefaultCount
= mAllDefaultTypeCount
- QuestionDefaultInfo
.mDefaultNumber
;
2204 sprintf (Msg
, "The question misses %d default, the question's opcode is %d", MissingDefaultCount
, pOpHead
->OpCode
);
2205 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, NULL
, "Error", Msg
);
2210 // parse next opcode.
2212 pNode
= pNode
->mNext
;
2216 CIfrRecordInfoDB gCIfrRecordInfoDB
;
2219 CIfrObj::_EMIT_PENDING_OBJ (
2223 CHAR8
*ObjBinBuf
= NULL
;
2228 if (!mDelayEmit
|| !gCreateOp
) {
2232 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2234 // update data buffer to package data
2236 ObjBinBuf
= gCFormPkg
.IfrBinBufferGet (mObjBinLen
);
2237 if (ObjBinBuf
!= NULL
) {
2238 memmove (ObjBinBuf
, mObjBinBuf
, mObjBinLen
);
2242 // update bin buffer to package data buffer
2244 if (mObjBinBuf
!= NULL
) {
2245 delete[] mObjBinBuf
;
2246 mObjBinBuf
= ObjBinBuf
;
2253 * The definition of CIfrObj's member function
2258 } gOpcodeSizesScopeTable
[] = {
2259 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2260 { sizeof (EFI_IFR_FORM
), 1 }, // EFI_IFR_FORM_OP
2261 { sizeof (EFI_IFR_SUBTITLE
), 1 }, // EFI_IFR_SUBTITLE_OP
2262 { sizeof (EFI_IFR_TEXT
), 0 }, // EFI_IFR_TEXT_OP
2263 { sizeof (EFI_IFR_IMAGE
), 0 }, // EFI_IFR_IMAGE_OP
2264 { sizeof (EFI_IFR_ONE_OF
), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2265 { sizeof (EFI_IFR_CHECKBOX
), 1}, // EFI_IFR_CHECKBOX_OP
2266 { sizeof (EFI_IFR_NUMERIC
), 1 }, // EFI_IFR_NUMERIC_OP
2267 { sizeof (EFI_IFR_PASSWORD
), 1 }, // EFI_IFR_PASSWORD_OP
2268 { sizeof (EFI_IFR_ONE_OF_OPTION
), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2269 { sizeof (EFI_IFR_SUPPRESS_IF
), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2270 { sizeof (EFI_IFR_LOCKED
), 0 }, // EFI_IFR_LOCKED_OP
2271 { sizeof (EFI_IFR_ACTION
), 1 }, // EFI_IFR_ACTION_OP
2272 { sizeof (EFI_IFR_RESET_BUTTON
), 1 }, // EFI_IFR_RESET_BUTTON_OP
2273 { sizeof (EFI_IFR_FORM_SET
), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2274 { sizeof (EFI_IFR_REF
), 0 }, // EFI_IFR_REF_OP
2275 { sizeof (EFI_IFR_NO_SUBMIT_IF
), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2276 { sizeof (EFI_IFR_INCONSISTENT_IF
), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2277 { sizeof (EFI_IFR_EQ_ID_VAL
), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2278 { sizeof (EFI_IFR_EQ_ID_ID
), 0 }, // EFI_IFR_EQ_ID_ID_OP
2279 { sizeof (EFI_IFR_EQ_ID_VAL_LIST
), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2280 { sizeof (EFI_IFR_AND
), 0 }, // EFI_IFR_AND_OP
2281 { sizeof (EFI_IFR_OR
), 0 }, // EFI_IFR_OR_OP
2282 { sizeof (EFI_IFR_NOT
), 0 }, // EFI_IFR_NOT_OP
2283 { sizeof (EFI_IFR_RULE
), 1 }, // EFI_IFR_RULE_OP
2284 { sizeof (EFI_IFR_GRAY_OUT_IF
), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2285 { sizeof (EFI_IFR_DATE
), 1 }, // EFI_IFR_DATE_OP
2286 { sizeof (EFI_IFR_TIME
), 1 }, // EFI_IFR_TIME_OP
2287 { sizeof (EFI_IFR_STRING
), 1 }, // EFI_IFR_STRING_OP
2288 { sizeof (EFI_IFR_REFRESH
), 0 }, // EFI_IFR_REFRESH_OP
2289 { sizeof (EFI_IFR_DISABLE_IF
), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2291 { sizeof (EFI_IFR_TO_LOWER
), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2292 { sizeof (EFI_IFR_TO_UPPER
), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2293 { sizeof (EFI_IFR_MAP
), 1 }, // EFI_IFR_MAP - 0x22
2294 { sizeof (EFI_IFR_ORDERED_LIST
), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2295 { sizeof (EFI_IFR_VARSTORE
), 0 }, // EFI_IFR_VARSTORE_OP
2296 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE
), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2297 { sizeof (EFI_IFR_VARSTORE_EFI
), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2298 { sizeof (EFI_IFR_VARSTORE_DEVICE
), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2299 { sizeof (EFI_IFR_VERSION
), 0 }, // EFI_IFR_VERSION_OP - 0x28
2300 { sizeof (EFI_IFR_END
), 0 }, // EFI_IFR_END_OP
2301 { sizeof (EFI_IFR_MATCH
), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2302 { sizeof (EFI_IFR_GET
), 0 }, // EFI_IFR_GET - 0x2B
2303 { sizeof (EFI_IFR_SET
), 0 }, // EFI_IFR_SET - 0x2C
2304 { sizeof (EFI_IFR_READ
), 0 }, // EFI_IFR_READ - 0x2D
2305 { sizeof (EFI_IFR_WRITE
), 0 }, // EFI_IFR_WRITE - 0x2E
2306 { sizeof (EFI_IFR_EQUAL
), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2307 { sizeof (EFI_IFR_NOT_EQUAL
), 0 }, // EFI_IFR_NOT_EQUAL_OP
2308 { sizeof (EFI_IFR_GREATER_THAN
), 0 }, // EFI_IFR_GREATER_THAN_OP
2309 { sizeof (EFI_IFR_GREATER_EQUAL
), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2310 { sizeof (EFI_IFR_LESS_THAN
), 0 }, // EFI_IFR_LESS_THAN_OP
2311 { sizeof (EFI_IFR_LESS_EQUAL
), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2312 { sizeof (EFI_IFR_BITWISE_AND
), 0 }, // EFI_IFR_BITWISE_AND_OP
2313 { sizeof (EFI_IFR_BITWISE_OR
), 0 }, // EFI_IFR_BITWISE_OR_OP
2314 { sizeof (EFI_IFR_BITWISE_NOT
), 0 }, // EFI_IFR_BITWISE_NOT_OP
2315 { sizeof (EFI_IFR_SHIFT_LEFT
), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2316 { sizeof (EFI_IFR_SHIFT_RIGHT
), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2317 { sizeof (EFI_IFR_ADD
), 0 }, // EFI_IFR_ADD_OP - 0x3A
2318 { sizeof (EFI_IFR_SUBTRACT
), 0 }, // EFI_IFR_SUBTRACT_OP
2319 { sizeof (EFI_IFR_MULTIPLY
), 0 }, // EFI_IFR_MULTIPLY_OP
2320 { sizeof (EFI_IFR_DIVIDE
), 0 }, // EFI_IFR_DIVIDE_OP
2321 { sizeof (EFI_IFR_MODULO
), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2322 { sizeof (EFI_IFR_RULE_REF
), 0 }, // EFI_IFR_RULE_REF_OP
2323 { sizeof (EFI_IFR_QUESTION_REF1
), 0 }, // EFI_IFR_QUESTION_REF1_OP
2324 { sizeof (EFI_IFR_QUESTION_REF2
), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2325 { sizeof (EFI_IFR_UINT8
), 0}, // EFI_IFR_UINT8
2326 { sizeof (EFI_IFR_UINT16
), 0}, // EFI_IFR_UINT16
2327 { sizeof (EFI_IFR_UINT32
), 0}, // EFI_IFR_UINT32
2328 { sizeof (EFI_IFR_UINT64
), 0}, // EFI_IFR_UTNT64
2329 { sizeof (EFI_IFR_TRUE
), 0 }, // EFI_IFR_TRUE_OP - 0x46
2330 { sizeof (EFI_IFR_FALSE
), 0 }, // EFI_IFR_FALSE_OP
2331 { sizeof (EFI_IFR_TO_UINT
), 0 }, // EFI_IFR_TO_UINT_OP
2332 { sizeof (EFI_IFR_TO_STRING
), 0 }, // EFI_IFR_TO_STRING_OP
2333 { sizeof (EFI_IFR_TO_BOOLEAN
), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2334 { sizeof (EFI_IFR_MID
), 0 }, // EFI_IFR_MID_OP
2335 { sizeof (EFI_IFR_FIND
), 0 }, // EFI_IFR_FIND_OP
2336 { sizeof (EFI_IFR_TOKEN
), 0 }, // EFI_IFR_TOKEN_OP
2337 { sizeof (EFI_IFR_STRING_REF1
), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2338 { sizeof (EFI_IFR_STRING_REF2
), 0 }, // EFI_IFR_STRING_REF2_OP
2339 { sizeof (EFI_IFR_CONDITIONAL
), 0 }, // EFI_IFR_CONDITIONAL_OP
2340 { sizeof (EFI_IFR_QUESTION_REF3
), 0 }, // EFI_IFR_QUESTION_REF3_OP
2341 { sizeof (EFI_IFR_ZERO
), 0 }, // EFI_IFR_ZERO_OP
2342 { sizeof (EFI_IFR_ONE
), 0 }, // EFI_IFR_ONE_OP
2343 { sizeof (EFI_IFR_ONES
), 0 }, // EFI_IFR_ONES_OP
2344 { sizeof (EFI_IFR_UNDEFINED
), 0 }, // EFI_IFR_UNDEFINED_OP
2345 { sizeof (EFI_IFR_LENGTH
), 0 }, // EFI_IFR_LENGTH_OP
2346 { sizeof (EFI_IFR_DUP
), 0 }, // EFI_IFR_DUP_OP - 0x57
2347 { sizeof (EFI_IFR_THIS
), 0 }, // EFI_IFR_THIS_OP
2348 { sizeof (EFI_IFR_SPAN
), 0 }, // EFI_IFR_SPAN_OP
2349 { sizeof (EFI_IFR_VALUE
), 1 }, // EFI_IFR_VALUE_OP
2350 { sizeof (EFI_IFR_DEFAULT
), 0 }, // EFI_IFR_DEFAULT_OP
2351 { sizeof (EFI_IFR_DEFAULTSTORE
), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2352 { sizeof (EFI_IFR_FORM_MAP
), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2353 { sizeof (EFI_IFR_CATENATE
), 0 }, // EFI_IFR_CATENATE_OP
2354 { sizeof (EFI_IFR_GUID
), 0 }, // EFI_IFR_GUID_OP
2355 { sizeof (EFI_IFR_SECURITY
), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2356 { sizeof (EFI_IFR_MODAL_TAG
), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2357 { sizeof (EFI_IFR_REFRESH_ID
), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2358 { sizeof (EFI_IFR_WARNING_IF
), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2359 { sizeof (EFI_IFR_MATCH2
), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2362 #ifdef CIFROBJ_DEUBG
2365 } gIfrObjPrintDebugTable
[] = {
2366 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2367 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2368 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2369 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2370 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2371 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2372 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2373 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2374 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2375 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2376 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2377 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2378 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2379 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2380 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2381 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2382 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2386 CIFROBJ_DEBUG_PRINT (
2390 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable
[OpCode
].mIfrName
);
2394 #define CIFROBJ_DEBUG_PRINT(OpCode)
2398 BOOLEAN gCreateOp
= TRUE
;
2404 IN BOOLEAN DelayEmit
2407 mDelayEmit
= DelayEmit
;
2408 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2409 mObjBinLen
= (ObjBinLen
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: ObjBinLen
;
2410 mObjBinBuf
= ((DelayEmit
== FALSE
) && (gCreateOp
== TRUE
)) ? gCFormPkg
.IfrBinBufferGet (mObjBinLen
) : new CHAR8
[EFI_IFR_MAX_LENGTH
];
2411 mRecordIdx
= (gCreateOp
== TRUE
) ? gCIfrRecordInfoDB
.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf
, mObjBinLen
, mPkgOffset
) : EFI_IFR_RECORDINFO_IDX_INVALUD
;
2414 assert (mObjBinBuf
!= NULL
);
2416 if (IfrObj
!= NULL
) {
2417 *IfrObj
= mObjBinBuf
;
2420 CIFROBJ_DEBUG_PRINT (OpCode
);
2427 if ((mDelayEmit
== TRUE
) && ((gCreateOp
== TRUE
))) {
2428 _EMIT_PENDING_OBJ ();
2431 gCIfrRecordInfoDB
.IfrRecordInfoUpdate (mRecordIdx
, mLineNo
, mObjBinBuf
, mObjBinLen
, mPkgOffset
);
2435 * The definition of CIfrObj's member function
2437 UINT8 gScopeCount
= 0;
2439 CIfrOpHeader::CIfrOpHeader (
2443 ) : mHeader ((EFI_IFR_OP_HEADER
*)StartAddr
)
2445 mHeader
->OpCode
= OpCode
;
2446 mHeader
->Length
= (Length
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: Length
;
2447 mHeader
->Scope
= (gOpcodeSizesScopeTable
[OpCode
].mScope
+ gScopeCount
> 0) ? 1 : 0;
2450 CIfrOpHeader::CIfrOpHeader (
2451 IN CIfrOpHeader
&OpHdr
2454 mHeader
= OpHdr
.mHeader
;
2457 UINT32
CIfrFormId::FormIdBitMap
[EFI_FREE_FORM_ID_BITMAP_SIZE
] = {0, };