3 The definition of CFormPkg's member function
5 Copyright (c) 2004 - 2017, 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.
18 #include "VfrFormPkg.h"
21 * The definition of CFormPkg's member function
24 SPendingAssign::SPendingAssign (
40 mKey
= new CHAR8
[strlen (Key
) + 1];
47 mMsg
= new CHAR8
[strlen (Msg
) + 1];
54 SPendingAssign::~SPendingAssign (
71 SPendingAssign::SetAddrAndLen (
81 SPendingAssign::AssignValue (
86 memmove (mAddr
, Addr
, (mLen
< Len
? mLen
: Len
));
91 SPendingAssign::GetKey (
108 mBufferNodeQueueHead
= NULL
;
109 mBufferNodeQueueTail
= NULL
;
110 mCurrBufferNode
= NULL
;
111 mReadBufferNode
= NULL
;
112 mReadBufferOffset
= 0;
113 PendingAssignList
= NULL
;
115 Node
= new SBufferNode
;
119 BufferStart
= new CHAR8
[BufferSize
];
120 if (BufferStart
== NULL
) {
124 BufferEnd
= BufferStart
+ BufferSize
;
126 memset (BufferStart
, 0, BufferSize
);
127 Node
->mBufferStart
= BufferStart
;
128 Node
->mBufferEnd
= BufferEnd
;
129 Node
->mBufferFree
= BufferStart
;
132 mBufferSize
= BufferSize
;
133 mBufferNodeQueueHead
= Node
;
134 mBufferNodeQueueTail
= Node
;
135 mCurrBufferNode
= Node
;
138 CFormPkg::~CFormPkg ()
141 SPendingAssign
*pPNode
;
143 while (mBufferNodeQueueHead
!= NULL
) {
144 pBNode
= mBufferNodeQueueHead
;
145 mBufferNodeQueueHead
= mBufferNodeQueueHead
->mNext
;
146 if (pBNode
->mBufferStart
!= NULL
) {
147 delete[] pBNode
->mBufferStart
;
151 mBufferNodeQueueTail
= NULL
;
152 mCurrBufferNode
= NULL
;
154 while (PendingAssignList
!= NULL
) {
155 pPNode
= PendingAssignList
;
156 PendingAssignList
= PendingAssignList
->mNext
;
159 PendingAssignList
= NULL
;
163 CFormPkg::CreateNewNode (
169 Node
= new SBufferNode
;
174 Node
->mBufferStart
= new CHAR8
[mBufferSize
];
175 if (Node
->mBufferStart
== NULL
) {
179 memset (Node
->mBufferStart
, 0, mBufferSize
);
180 Node
->mBufferEnd
= Node
->mBufferStart
+ mBufferSize
;
181 Node
->mBufferFree
= Node
->mBufferStart
;
189 CFormPkg::IfrBinBufferGet (
193 CHAR8
*BinBuffer
= NULL
;
194 SBufferNode
*Node
= NULL
;
196 if ((Len
== 0) || (Len
> mBufferSize
)) {
200 if ((mCurrBufferNode
->mBufferFree
+ Len
) <= mCurrBufferNode
->mBufferEnd
) {
201 BinBuffer
= mCurrBufferNode
->mBufferFree
;
202 mCurrBufferNode
->mBufferFree
+= Len
;
204 Node
= CreateNewNode ();
209 if (mBufferNodeQueueTail
== NULL
) {
210 mBufferNodeQueueHead
= mBufferNodeQueueTail
= Node
;
212 mBufferNodeQueueTail
->mNext
= Node
;
213 mBufferNodeQueueTail
= Node
;
215 mCurrBufferNode
= Node
;
220 BinBuffer
= mCurrBufferNode
->mBufferFree
;
221 mCurrBufferNode
->mBufferFree
+= Len
;
231 CFormPkg::GetPkgLength (
243 mReadBufferNode
= mBufferNodeQueueHead
;
244 mReadBufferOffset
= 0;
252 mReadBufferNode
= NULL
;
253 mReadBufferOffset
= 0;
264 if ((Size
== 0) || (Buffer
== NULL
)) {
268 if (mReadBufferNode
== NULL
) {
272 for (Index
= 0; Index
< Size
; Index
++) {
273 if ((mReadBufferNode
->mBufferStart
+ mReadBufferOffset
) < mReadBufferNode
->mBufferFree
) {
274 Buffer
[Index
] = mReadBufferNode
->mBufferStart
[mReadBufferOffset
++];
276 if ((mReadBufferNode
= mReadBufferNode
->mNext
) == NULL
) {
279 mReadBufferOffset
= 0;
289 CFormPkg::BuildPkgHdr (
290 OUT EFI_HII_PACKAGE_HEADER
**PkgHdr
293 if (PkgHdr
== NULL
) {
294 return VFR_RETURN_FATAL_ERROR
;
297 if (((*PkgHdr
) = new EFI_HII_PACKAGE_HEADER
) == NULL
) {
298 return VFR_RETURN_OUT_FOR_RESOURCES
;
301 (*PkgHdr
)->Type
= EFI_HII_PACKAGE_FORM
;
302 (*PkgHdr
)->Length
= mPkgLength
+ sizeof (EFI_HII_PACKAGE_HEADER
);
304 return VFR_RETURN_SUCCESS
;
309 OUT PACKAGE_DATA
&TBuffer
317 if (TBuffer
.Buffer
!= NULL
) {
318 delete TBuffer
.Buffer
;
321 TBuffer
.Size
= mPkgLength
;
322 TBuffer
.Buffer
= NULL
;
323 if (TBuffer
.Size
!= 0) {
324 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
326 return VFR_RETURN_SUCCESS
;
329 Temp
= TBuffer
.Buffer
;
331 while ((Size
= Read (Buffer
, 1024)) != 0) {
332 memcpy (Temp
, Buffer
, Size
);
336 return VFR_RETURN_SUCCESS
;
343 IN PACKAGE_DATA
*PkgData
346 EFI_VFR_RETURN_CODE Ret
;
349 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
351 if (Output
== NULL
) {
352 return VFR_RETURN_FATAL_ERROR
;
355 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
358 fwrite (PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
), 1, Output
);
361 if (PkgData
== NULL
) {
363 while ((Size
= Read (Buffer
, 1024)) != 0) {
364 fwrite (Buffer
, Size
, 1, Output
);
368 fwrite (PkgData
->Buffer
, PkgData
->Size
, 1, Output
);
371 return VFR_RETURN_SUCCESS
;
375 CFormPkg::_WRITE_PKG_LINE (
378 IN CONST CHAR8
*LineHeader
,
385 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
389 for (Index
= 0; Index
< BlkSize
; Index
++) {
390 if ((Index
% LineBytes
) == 0) {
391 fprintf (pFile
, "\n%s", LineHeader
);
393 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
398 CFormPkg::_WRITE_PKG_END (
401 IN CONST CHAR8
*LineHeader
,
408 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
412 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
413 if ((Index
% LineBytes
) == 0) {
414 fprintf (pFile
, "\n%s", LineHeader
);
416 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
419 if ((Index
% LineBytes
) == 0) {
420 fprintf (pFile
, "\n%s", LineHeader
);
422 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
425 #define BYTES_PRE_LINE 0x10
426 UINT32 gAdjustOpcodeOffset
= 0;
427 BOOLEAN gNeedAdjustOpcode
= FALSE
;
428 UINT32 gAdjustOpcodeLen
= 0;
434 IN PACKAGE_DATA
*PkgData
437 EFI_VFR_RETURN_CODE Ret
;
438 CHAR8 Buffer
[BYTES_PRE_LINE
* 8];
439 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
440 UINT32 PkgLength
= 0;
443 if ((BaseName
== NULL
) || (pFile
== NULL
)) {
444 return VFR_RETURN_FATAL_ERROR
;
447 fprintf (pFile
, "\nunsigned char %sBin[] = {\n", BaseName
);
449 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
454 // For framework vfr file, the extension framework header will be added.
456 if (VfrCompatibleMode
) {
457 fprintf (pFile
, " // FRAMEWORK PACKAGE HEADER Length\n");
458 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
) + 2;
459 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
460 fprintf (pFile
, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
462 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT16
));
464 fprintf (pFile
, " // ARRAY LENGTH\n");
465 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
);
466 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
469 fprintf (pFile
, "\n\n // PACKAGE HEADER\n");
470 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
471 PkgLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
473 fprintf (pFile
, "\n\n // PACKAGE DATA\n");
475 if (PkgData
== NULL
) {
477 while ((ReadSize
= Read ((CHAR8
*)Buffer
, BYTES_PRE_LINE
* 8)) != 0) {
478 PkgLength
+= ReadSize
;
479 if (PkgLength
< PkgHdr
->Length
) {
480 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
482 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
487 if (PkgData
->Size
% BYTES_PRE_LINE
!= 0) {
488 PkgLength
= PkgData
->Size
- (PkgData
->Size
% BYTES_PRE_LINE
);
489 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
490 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, PkgData
->Size
% BYTES_PRE_LINE
);
492 PkgLength
= PkgData
->Size
- BYTES_PRE_LINE
;
493 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
494 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, BYTES_PRE_LINE
);
499 fprintf (pFile
, "\n};\n");
501 return VFR_RETURN_SUCCESS
;
505 CFormPkg::AssignPending (
513 SPendingAssign
*pNew
;
515 pNew
= new SPendingAssign (Key
, ValAddr
, ValLen
, LineNo
, Msg
);
517 return VFR_RETURN_OUT_FOR_RESOURCES
;
520 pNew
->mNext
= PendingAssignList
;
521 PendingAssignList
= pNew
;
522 return VFR_RETURN_SUCCESS
;
526 CFormPkg::DoPendingAssign (
532 SPendingAssign
*pNode
;
534 if ((Key
== NULL
) || (ValAddr
== NULL
)) {
538 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
539 if (strcmp (pNode
->mKey
, Key
) == 0) {
540 pNode
->AssignValue (ValAddr
, ValLen
);
546 CFormPkg::HavePendingUnassigned (
550 SPendingAssign
*pNode
;
552 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
553 if (pNode
->mFlag
== PENDING
) {
562 CFormPkg::PendingAssignPrintAll (
566 SPendingAssign
*pNode
;
568 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
569 if (pNode
->mFlag
== PENDING
) {
570 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", pNode
->mMsg
);
576 CFormPkg::GetBinBufferNodeForAddr (
577 IN CHAR8
*BinBuffAddr
580 SBufferNode
*TmpNode
;
582 TmpNode
= mBufferNodeQueueHead
;
584 while (TmpNode
!= NULL
) {
585 if (TmpNode
->mBufferStart
<= BinBuffAddr
&& TmpNode
->mBufferFree
>= BinBuffAddr
) {
589 TmpNode
= TmpNode
->mNext
;
596 CFormPkg::GetNodeBefore(
597 IN SBufferNode
*CurrentNode
600 SBufferNode
*FirstNode
= mBufferNodeQueueHead
;
601 SBufferNode
*LastNode
= mBufferNodeQueueHead
;
603 while (FirstNode
!= NULL
) {
604 if (FirstNode
== CurrentNode
) {
608 LastNode
= FirstNode
;
609 FirstNode
= FirstNode
->mNext
;
612 if (FirstNode
== NULL
) {
620 CFormPkg::InsertNodeBefore(
621 IN SBufferNode
*CurrentNode
,
622 IN SBufferNode
*NewNode
625 SBufferNode
*LastNode
= GetNodeBefore (CurrentNode
);
627 if (LastNode
== NULL
) {
628 return VFR_RETURN_MISMATCHED
;
631 NewNode
->mNext
= LastNode
->mNext
;
632 LastNode
->mNext
= NewNode
;
634 return VFR_RETURN_SUCCESS
;
638 CFormPkg::GetBufAddrBaseOnOffset (
642 SBufferNode
*TmpNode
;
644 UINT32 CurrentBufLen
;
648 for (TmpNode
= mBufferNodeQueueHead
; TmpNode
!= NULL
; TmpNode
= TmpNode
->mNext
) {
649 CurrentBufLen
= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
650 if (Offset
>= TotalBufLen
&& Offset
< TotalBufLen
+ CurrentBufLen
) {
651 return TmpNode
->mBufferStart
+ (Offset
- TotalBufLen
);
654 TotalBufLen
+= CurrentBufLen
;
661 CFormPkg::AdjustDynamicInsertOpcode (
662 IN CHAR8
*InserPositionAddr
,
663 IN CHAR8
*InsertOpcodeAddr
,
664 IN BOOLEAN CreateOpcodeAfterParsingVfr
667 SBufferNode
*InserPositionNode
;
668 SBufferNode
*InsertOpcodeNode
;
669 SBufferNode
*NewRestoreNodeBegin
;
670 SBufferNode
*NewRestoreNodeEnd
;
671 SBufferNode
*NewLastEndNode
;
672 SBufferNode
*TmpNode
;
673 UINT32 NeedRestoreCodeLen
;
675 NewRestoreNodeEnd
= NULL
;
677 InserPositionNode
= GetBinBufferNodeForAddr(InserPositionAddr
);
678 InsertOpcodeNode
= GetBinBufferNodeForAddr(InsertOpcodeAddr
);
679 assert (InserPositionNode
!= NULL
);
680 assert (InsertOpcodeNode
!= NULL
);
682 if (InserPositionNode
== InsertOpcodeNode
) {
684 // Create New Node to save the restore opcode.
686 NeedRestoreCodeLen
= InsertOpcodeAddr
- InserPositionAddr
;
687 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
688 NewRestoreNodeBegin
= CreateNewNode ();
689 if (NewRestoreNodeBegin
== NULL
) {
690 return VFR_RETURN_OUT_FOR_RESOURCES
;
692 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
693 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
696 // Override the restore buffer data.
698 memmove (InserPositionAddr
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
699 InsertOpcodeNode
->mBufferFree
-= NeedRestoreCodeLen
;
700 memset (InsertOpcodeNode
->mBufferFree
, 0, NeedRestoreCodeLen
);
703 // Create New Node to save the restore opcode.
705 NeedRestoreCodeLen
= InserPositionNode
->mBufferFree
- InserPositionAddr
;
706 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
707 NewRestoreNodeBegin
= CreateNewNode ();
708 if (NewRestoreNodeBegin
== NULL
) {
709 return VFR_RETURN_OUT_FOR_RESOURCES
;
711 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
712 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
714 // Override the restore buffer data.
716 InserPositionNode
->mBufferFree
-= NeedRestoreCodeLen
;
718 // Link the restore data to new node.
720 NewRestoreNodeBegin
->mNext
= InserPositionNode
->mNext
;
723 // Count the Adjust opcode len.
725 TmpNode
= InserPositionNode
->mNext
;
726 while (TmpNode
!= InsertOpcodeNode
) {
727 gAdjustOpcodeLen
+= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
728 TmpNode
= TmpNode
->mNext
;
732 // Create New Node to save the last node of restore opcode.
734 NeedRestoreCodeLen
= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
735 gAdjustOpcodeLen
+= NeedRestoreCodeLen
;
736 if (NeedRestoreCodeLen
> 0) {
737 NewRestoreNodeEnd
= CreateNewNode ();
738 if (NewRestoreNodeEnd
== NULL
) {
739 return VFR_RETURN_OUT_FOR_RESOURCES
;
741 memcpy (NewRestoreNodeEnd
->mBufferFree
, InsertOpcodeNode
->mBufferStart
, NeedRestoreCodeLen
);
742 NewRestoreNodeEnd
->mBufferFree
+= NeedRestoreCodeLen
;
744 // Override the restore buffer data.
746 memmove (InsertOpcodeNode
->mBufferStart
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
747 InsertOpcodeNode
->mBufferFree
-= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
750 // Insert the last restore data node.
752 TmpNode
= GetNodeBefore (InsertOpcodeNode
);
753 assert (TmpNode
!= NULL
);
755 if (TmpNode
== InserPositionNode
) {
756 NewRestoreNodeBegin
->mNext
= NewRestoreNodeEnd
;
758 TmpNode
->mNext
= NewRestoreNodeEnd
;
761 // Connect the dynamic opcode node to the node after InserPositionNode.
763 InserPositionNode
->mNext
= InsertOpcodeNode
;
767 if (CreateOpcodeAfterParsingVfr
) {
769 // Th new opcodes were created after Parsing Vfr file,
770 // so the content in mBufferNodeQueueTail must be the new created opcodes.
771 // So connet the NewRestoreNodeBegin to the tail and update the tail node.
773 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
774 if (NewRestoreNodeEnd
!= NULL
) {
775 mBufferNodeQueueTail
= NewRestoreNodeEnd
;
777 mBufferNodeQueueTail
= NewRestoreNodeBegin
;
780 if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
> 2) {
782 // End form set opcode all in the mBufferNodeQueueTail node.
784 NewLastEndNode
= CreateNewNode ();
785 if (NewLastEndNode
== NULL
) {
786 return VFR_RETURN_OUT_FOR_RESOURCES
;
788 NewLastEndNode
->mBufferStart
[0] = 0x29;
789 NewLastEndNode
->mBufferStart
[1] = 0x02;
790 NewLastEndNode
->mBufferFree
+= 2;
792 mBufferNodeQueueTail
->mBufferFree
-= 2;
794 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
795 if (NewRestoreNodeEnd
!= NULL
) {
796 NewRestoreNodeEnd
->mNext
= NewLastEndNode
;
798 NewRestoreNodeBegin
->mNext
= NewLastEndNode
;
801 mBufferNodeQueueTail
= NewLastEndNode
;
802 } else if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
== 2) {
803 TmpNode
= GetNodeBefore(mBufferNodeQueueTail
);
804 assert (TmpNode
!= NULL
);
806 TmpNode
->mNext
= NewRestoreNodeBegin
;
807 if (NewRestoreNodeEnd
!= NULL
) {
808 NewRestoreNodeEnd
->mNext
= mBufferNodeQueueTail
;
810 NewRestoreNodeBegin
->mNext
= mBufferNodeQueueTail
;
814 mCurrBufferNode
= mBufferNodeQueueTail
;
815 return VFR_RETURN_SUCCESS
;
819 CFormPkg::DeclarePendingQuestion (
820 IN CVfrVarDataTypeDB
&lCVfrVarDataTypeDB
,
821 IN CVfrDataStorage
&lCVfrDataStorage
,
822 IN CVfrQuestionDB
&lCVfrQuestionDB
,
823 IN EFI_GUID
*LocalFormSetGuid
,
825 OUT CHAR8
**InsertOpcodeAddr
828 SPendingAssign
*pNode
;
831 CHAR8 FName
[MAX_NAME_LEN
];
834 UINT32 ShrinkSize
= 0;
835 EFI_VFR_RETURN_CODE ReturnCode
;
836 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
839 CIfrGuid
*GuidObj
= NULL
;
842 // Declare all questions as Numeric in DisableIf True
846 DIObj
.SetLineNo (LineNo
);
847 *InsertOpcodeAddr
= DIObj
.GetObjBinAddr
<CHAR8
>();
850 CIfrTrue
TObj (LineNo
);
852 // Declare Numeric qeustion for each undefined question.
853 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
854 if (pNode
->mFlag
== PENDING
) {
855 EFI_VARSTORE_INFO Info
;
856 EFI_QUESTION_ID QId
= EFI_QUESTION_ID_INVALID
;
858 // Register this question, assume it is normal question, not date or time question
860 VarStr
= pNode
->mKey
;
861 ReturnCode
= lCVfrQuestionDB
.RegisterQuestion (NULL
, VarStr
, QId
);
862 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
863 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
868 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr
, QId
);
871 // Get Question Info, framework vfr VarName == StructName
873 ReturnCode
= lCVfrVarDataTypeDB
.ExtractFieldNameAndArrary (VarStr
, FName
, ArrayIdx
);
874 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
875 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", "Var string is not the valid C variable");
881 ReturnCode
= lCVfrDataStorage
.GetVarStoreId (FName
, &Info
.mVarStoreId
);
882 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
883 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, FName
, "Error", "Var Store Type is not defined");
886 VarStoreType
= lCVfrDataStorage
.GetVarStoreType (Info
.mVarStoreId
);
888 if (*VarStr
== '\0' && ArrayIdx
!= INVALID_ARRAY_INDEX
) {
889 ReturnCode
= lCVfrDataStorage
.GetNameVarStoreInfo (&Info
, ArrayIdx
);
891 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
892 ReturnCode
= lCVfrDataStorage
.GetEfiVarStoreInfo (&Info
);
893 } else if (VarStoreType
== EFI_VFR_VARSTORE_BUFFER
|| VarStoreType
== EFI_VFR_VARSTORE_BUFFER_BITS
) {
894 VarStr
= pNode
->mKey
;
895 //convert VarStr with store name to VarStr with structure name
896 ReturnCode
= lCVfrDataStorage
.GetBufferVarStoreDataTypeName (Info
.mVarStoreId
, &SName
);
897 if (ReturnCode
== VFR_RETURN_SUCCESS
) {
898 NewStr
= new CHAR8
[strlen (VarStr
) + strlen (SName
) + 1];
900 strcpy (NewStr
, SName
);
901 strcat (NewStr
, VarStr
+ strlen (FName
));
902 ReturnCode
= lCVfrVarDataTypeDB
.GetDataFieldInfo (NewStr
, Info
.mInfo
.mVarOffset
, Info
.mVarType
, Info
.mVarTotalSize
, Info
.mIsBitVar
);
906 ReturnCode
= VFR_RETURN_UNSUPPORTED
;
909 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
910 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
914 // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.
916 if (Info
.mIsBitVar
) {
917 GuidObj
= new CIfrGuid(0);
918 GuidObj
->SetGuid (&gEdkiiIfrBitVarGuid
);
919 GuidObj
->SetLineNo(LineNo
);
923 CNObj
.SetLineNo (LineNo
);
924 CNObj
.SetPrompt (0x0);
926 CNObj
.SetQuestionId (QId
);
927 CNObj
.SetVarStoreInfo (&Info
);
930 // 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.
932 if (Info
.mIsBitVar
) {
933 MaxValue
= (1 << Info
.mVarTotalSize
) -1;
934 CNObj
.SetMinMaxStepData ((UINT32
) 0, MaxValue
, (UINT32
) 0);
936 LFlags
= (EDKII_IFR_NUMERIC_SIZE_BIT
& Info
.mVarTotalSize
);
937 CNObj
.SetFlagsForBitField (0, LFlags
);
940 // Numeric doesn't support BOOLEAN data type.
941 // BOOLEAN type has the same data size to UINT8.
943 if (Info
.mVarType
== EFI_IFR_TYPE_BOOLEAN
) {
944 Info
.mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
946 CNObj
.SetFlags (0, Info
.mVarType
);
948 // Use maximum value not to limit the vaild value for the undefined question.
950 switch (Info
.mVarType
) {
951 case EFI_IFR_TYPE_NUM_SIZE_64
:
952 CNObj
.SetMinMaxStepData ((UINT64
) 0, (UINT64
) -1 , (UINT64
) 0);
955 case EFI_IFR_TYPE_NUM_SIZE_32
:
956 CNObj
.SetMinMaxStepData ((UINT32
) 0, (UINT32
) -1 , (UINT32
) 0);
959 case EFI_IFR_TYPE_NUM_SIZE_16
:
960 CNObj
.SetMinMaxStepData ((UINT16
) 0, (UINT16
) -1 , (UINT16
) 0);
963 case EFI_IFR_TYPE_NUM_SIZE_8
:
964 CNObj
.SetMinMaxStepData ((UINT8
) 0, (UINT8
) -1 , (UINT8
) 0);
971 CNObj
.ShrinkBinSize (ShrinkSize
);
974 // For undefined Efi VarStore type question
975 // Append the extended guided opcode to contain VarName
977 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
|| VfrCompatibleMode
) {
978 CIfrVarEqName
CVNObj (QId
, Info
.mInfo
.mVarName
);
979 CVNObj
.SetLineNo (LineNo
);
986 CEObj
.SetLineNo (LineNo
);
988 // End for Guided opcode
990 if (GuidObj
!= NULL
) {
992 CEObjGuid
.SetLineNo (LineNo
);
993 GuidObj
->SetScope(1);
1001 // End for DisableIf
1004 SEObj
.SetLineNo (LineNo
);
1006 return VFR_RETURN_SUCCESS
;
1011 SIfrRecord::SIfrRecord (
1017 mLineNo
= 0xFFFFFFFF;
1018 mOffset
= 0xFFFFFFFF;
1022 SIfrRecord::~SIfrRecord (
1026 if (mIfrBinBuf
!= NULL
) {
1027 //delete mIfrBinBuf;
1030 mLineNo
= 0xFFFFFFFF;
1031 mOffset
= 0xFFFFFFFF;
1036 CIfrRecordInfoDB::CIfrRecordInfoDB (
1041 mRecordCount
= EFI_IFR_RECORDINFO_IDX_START
;
1042 mIfrRecordListHead
= NULL
;
1043 mIfrRecordListTail
= NULL
;
1044 mAllDefaultTypeCount
= 0;
1045 for (UINT8 i
= 0; i
< EFI_HII_MAX_SUPPORT_DEFAULT_TYPE
; i
++) {
1046 mAllDefaultIdArray
[i
] = 0xffff;
1050 CIfrRecordInfoDB::~CIfrRecordInfoDB (
1056 while (mIfrRecordListHead
!= NULL
) {
1057 pNode
= mIfrRecordListHead
;
1058 mIfrRecordListHead
= mIfrRecordListHead
->mNext
;
1064 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1069 SIfrRecord
*pNode
= NULL
;
1071 if (RecordIdx
== EFI_IFR_RECORDINFO_IDX_INVALUD
) {
1075 for (Idx
= (EFI_IFR_RECORDINFO_IDX_START
+ 1), pNode
= mIfrRecordListHead
;
1076 (Idx
!= RecordIdx
) && (pNode
!= NULL
);
1077 Idx
++, pNode
= pNode
->mNext
)
1084 CIfrRecordInfoDB::IfrRecordRegister (
1086 IN CHAR8
*IfrBinBuf
,
1093 if (mSwitch
== FALSE
) {
1094 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1097 if ((pNew
= new SIfrRecord
) == NULL
) {
1098 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1101 if (mIfrRecordListHead
== NULL
) {
1102 mIfrRecordListHead
= pNew
;
1103 mIfrRecordListTail
= pNew
;
1105 mIfrRecordListTail
->mNext
= pNew
;
1106 mIfrRecordListTail
= pNew
;
1110 return mRecordCount
;
1114 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1115 IN UINT32 RecordIdx
,
1125 if ((pNode
= GetRecordInfoFromIdx (RecordIdx
)) == NULL
) {
1131 // Line number is not specified explicitly, try to use line number of previous opcode
1133 Prev
= GetRecordInfoFromIdx (RecordIdx
- 1);
1135 LineNo
= Prev
->mLineNo
;
1139 pNode
->mLineNo
= LineNo
;
1140 pNode
->mOffset
= Offset
;
1141 pNode
->mBinBufLen
= BinBufLen
;
1142 pNode
->mIfrBinBuf
= BinBuf
;
1147 CIfrRecordInfoDB::IfrRecordOutput (
1148 OUT PACKAGE_DATA
&TBuffer
1154 if (TBuffer
.Buffer
!= NULL
) {
1155 delete[] TBuffer
.Buffer
;
1159 TBuffer
.Buffer
= NULL
;
1162 if (mSwitch
== FALSE
) {
1166 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1167 TBuffer
.Size
+= pNode
->mBinBufLen
;
1170 if (TBuffer
.Size
!= 0) {
1171 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
1176 Temp
= TBuffer
.Buffer
;
1178 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1179 if (pNode
->mIfrBinBuf
!= NULL
) {
1180 memcpy (Temp
, pNode
->mIfrBinBuf
, pNode
->mBinBufLen
);
1181 Temp
+= pNode
->mBinBufLen
;
1189 CIfrRecordInfoDB::IfrRecordOutput (
1198 if (mSwitch
== FALSE
) {
1208 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1209 if (pNode
->mLineNo
== LineNo
|| LineNo
== 0) {
1210 fprintf (File
, ">%08X: ", pNode
->mOffset
);
1211 TotalSize
+= pNode
->mBinBufLen
;
1212 if (pNode
->mIfrBinBuf
!= NULL
) {
1213 for (Index
= 0; Index
< pNode
->mBinBufLen
; Index
++) {
1214 fprintf (File
, "%02X ", (UINT8
)(pNode
->mIfrBinBuf
[Index
]));
1217 fprintf (File
, "\n");
1222 fprintf (File
, "\nTotal Size of all record is 0x%08X\n", TotalSize
);
1227 // for framework vfr file
1228 // adjust opcode sequence for uefi IFR format
1229 // adjust inconsistent and varstore into the right position.
1232 CIfrRecordInfoDB::CheckQuestionOpCode (
1237 case EFI_IFR_CHECKBOX_OP
:
1238 case EFI_IFR_NUMERIC_OP
:
1239 case EFI_IFR_PASSWORD_OP
:
1240 case EFI_IFR_ONE_OF_OP
:
1241 case EFI_IFR_ACTION_OP
:
1242 case EFI_IFR_STRING_OP
:
1243 case EFI_IFR_DATE_OP
:
1244 case EFI_IFR_TIME_OP
:
1245 case EFI_IFR_ORDERED_LIST_OP
:
1246 case EFI_IFR_REF_OP
:
1254 CIfrRecordInfoDB::CheckIdOpCode (
1259 case EFI_IFR_EQ_ID_VAL_OP
:
1260 case EFI_IFR_EQ_ID_ID_OP
:
1261 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1262 case EFI_IFR_QUESTION_REF1_OP
:
1270 CIfrRecordInfoDB::GetOpcodeQuestionId (
1271 IN EFI_IFR_OP_HEADER
*OpHead
1274 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1276 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (OpHead
+ 1);
1278 return QuestionHead
->QuestionId
;
1282 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1286 SIfrRecord
*pNode
= NULL
;
1288 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1289 if (pNode
->mOffset
== Offset
) {
1298 Add just the op code position.
1300 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1301 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1305 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1309 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1311 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1312 so new records are appennded to the end of OriginalIfrRecordListTail.
1316 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1320 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1323 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1327 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1328 IN BOOLEAN CreateOpcodeAfterParsingVfr
1331 UINT32 OpcodeOffset
;
1332 SIfrRecord
*pNode
, *pPreNode
;
1333 SIfrRecord
*pAdjustNode
, *pNodeBeforeAdjust
;
1334 SIfrRecord
*pNodeBeforeDynamic
;
1338 pNodeBeforeDynamic
= NULL
;
1342 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1343 // and the node before pDynamicOpcodeNode.
1345 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1346 if (OpcodeOffset
== gAdjustOpcodeOffset
) {
1347 pAdjustNode
= pNode
;
1348 pNodeBeforeAdjust
= pPreNode
;
1349 } else if (OpcodeOffset
== gAdjustOpcodeOffset
+ gAdjustOpcodeLen
) {
1350 pNodeBeforeDynamic
= pPreNode
;
1352 if (pNode
->mNext
!= NULL
) {
1355 OpcodeOffset
+= pNode
->mBinBufLen
;
1359 // Check the nodes whether exist.
1361 if (pNodeBeforeDynamic
== NULL
|| pAdjustNode
== NULL
|| pNodeBeforeAdjust
== NULL
) {
1366 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1368 pNodeBeforeAdjust
->mNext
= pNodeBeforeDynamic
->mNext
;
1369 if (CreateOpcodeAfterParsingVfr
) {
1371 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1373 mIfrRecordListTail
->mNext
= pAdjustNode
;
1374 mIfrRecordListTail
= pNodeBeforeDynamic
;
1375 mIfrRecordListTail
->mNext
= NULL
;
1378 //pPreNode is the end of pDynamicNode(Case1).
1380 pPreNode
->mNext
= pAdjustNode
;
1381 pNodeBeforeDynamic
->mNext
= mIfrRecordListTail
;
1388 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1390 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1394 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1395 IN BOOLEAN CreateOpcodeAfterParsingVfr
1398 SIfrRecord
*pRecord
;
1401 // Base on the original offset info to update the record list.
1403 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr
)) {
1404 gCVfrErrorHandle
.PrintMsg (0, (CHAR8
*)"Error", (CHAR8
*)"Can not find the adjust offset in the record.");
1408 // Base on the opcode binary length to recalculate the offset for each opcode.
1410 IfrAdjustOffsetForRecord();
1413 // Base on the offset to find the binary address.
1415 pRecord
= GetRecordInfoFromOffset(gAdjustOpcodeOffset
);
1416 while (pRecord
!= NULL
) {
1417 pRecord
->mIfrBinBuf
= gCFormPkg
.GetBufAddrBaseOnOffset(pRecord
->mOffset
);
1418 pRecord
= pRecord
->mNext
;
1424 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1428 UINT32 OpcodeOffset
;
1432 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1433 pNode
->mOffset
= OpcodeOffset
;
1434 OpcodeOffset
+= pNode
->mBinBufLen
;
1439 CIfrRecordInfoDB::IfrRecordAdjust (
1443 SIfrRecord
*pNode
, *preNode
;
1444 SIfrRecord
*uNode
, *tNode
;
1445 EFI_IFR_OP_HEADER
*OpHead
, *tOpHead
;
1446 EFI_QUESTION_ID QuestionId
;
1448 UINT32 QuestionScope
;
1449 CHAR8 ErrorMsg
[MAX_STRING_LEN
] = {0, };
1450 EFI_VFR_RETURN_CODE Status
;
1453 // Init local variable
1455 Status
= VFR_RETURN_SUCCESS
;
1456 pNode
= mIfrRecordListHead
;
1459 while (pNode
!= NULL
) {
1460 OpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1463 // make sure the inconsistent opcode in question scope
1465 if (QuestionScope
> 0) {
1466 QuestionScope
+= OpHead
->Scope
;
1467 if (OpHead
->OpCode
== EFI_IFR_END_OP
) {
1472 if (CheckQuestionOpCode (OpHead
->OpCode
)) {
1476 // for the inconsistent opcode not in question scope, adjust it
1478 if (OpHead
->OpCode
== EFI_IFR_INCONSISTENT_IF_OP
&& QuestionScope
== 0) {
1480 // for inconsistent opcode not in question scope
1484 // Count inconsistent opcode Scope
1486 StackCount
= OpHead
->Scope
;
1487 QuestionId
= EFI_QUESTION_ID_INVALID
;
1489 while (tNode
!= NULL
&& StackCount
> 0) {
1490 tNode
= tNode
->mNext
;
1491 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mIfrBinBuf
;
1493 // Calculate Scope Number
1495 StackCount
+= tOpHead
->Scope
;
1496 if (tOpHead
->OpCode
== EFI_IFR_END_OP
) {
1500 // by IdEqual opcode to get QuestionId
1502 if (QuestionId
== EFI_QUESTION_ID_INVALID
&&
1503 CheckIdOpCode (tOpHead
->OpCode
)) {
1504 QuestionId
= *(EFI_QUESTION_ID
*) (tOpHead
+ 1);
1507 if (tNode
== NULL
|| QuestionId
== EFI_QUESTION_ID_INVALID
) {
1509 // report error; not found
1511 sprintf (ErrorMsg
, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId
);
1512 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1513 Status
= VFR_RETURN_MISMATCHED
;
1517 // extract inconsistent opcode list
1518 // pNode is Incosistent opcode, tNode is End Opcode
1522 // insert inconsistent opcode list into the right question scope by questionid
1524 for (uNode
= mIfrRecordListHead
; uNode
!= NULL
; uNode
= uNode
->mNext
) {
1525 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mIfrBinBuf
;
1526 if (CheckQuestionOpCode (tOpHead
->OpCode
) &&
1527 (QuestionId
== GetOpcodeQuestionId (tOpHead
))) {
1532 // insert inconsistent opcode list and check LATE_CHECK flag
1534 if (uNode
!= NULL
) {
1535 if ((((EFI_IFR_QUESTION_HEADER
*)(tOpHead
+ 1))->Flags
& 0x20) != 0) {
1537 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1539 OpHead
->OpCode
= EFI_IFR_NO_SUBMIT_IF_OP
;
1543 // skip the default storage for Date and Time
1545 if ((uNode
->mNext
!= NULL
) && (*uNode
->mNext
->mIfrBinBuf
== EFI_IFR_DEFAULT_OP
)) {
1546 uNode
= uNode
->mNext
;
1549 preNode
->mNext
= tNode
->mNext
;
1550 tNode
->mNext
= uNode
->mNext
;
1551 uNode
->mNext
= pNode
;
1553 // reset pNode to head list, scan the whole list again.
1555 pNode
= mIfrRecordListHead
;
1561 // not found matched question id, report error
1563 sprintf (ErrorMsg
, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId
);
1564 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1565 Status
= VFR_RETURN_MISMATCHED
;
1568 } else if (OpHead
->OpCode
== EFI_IFR_VARSTORE_OP
||
1569 OpHead
->OpCode
== EFI_IFR_VARSTORE_EFI_OP
) {
1571 // for new added group of varstore opcode
1574 while (tNode
->mNext
!= NULL
) {
1575 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mNext
->mIfrBinBuf
;
1576 if (tOpHead
->OpCode
!= EFI_IFR_VARSTORE_OP
&&
1577 tOpHead
->OpCode
!= EFI_IFR_VARSTORE_EFI_OP
) {
1580 tNode
= tNode
->mNext
;
1583 if (tNode
->mNext
== NULL
) {
1585 // invalid IfrCode, IfrCode end by EndOpCode
1587 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", "No found End Opcode in the end");
1588 Status
= VFR_RETURN_MISMATCHED
;
1592 if (tOpHead
->OpCode
!= EFI_IFR_END_OP
) {
1594 // not new added varstore, which are not needed to be adjust.
1597 pNode
= tNode
->mNext
;
1601 // move new added varstore opcode to the position befor form opcode
1602 // varstore opcode between pNode and tNode
1606 // search form opcode from begin
1608 for (uNode
= mIfrRecordListHead
; uNode
->mNext
!= NULL
; uNode
= uNode
->mNext
) {
1609 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mNext
->mIfrBinBuf
;
1610 if (tOpHead
->OpCode
== EFI_IFR_FORM_OP
) {
1615 // Insert varstore opcode beform form opcode if form opcode is found
1617 if (uNode
->mNext
!= NULL
) {
1618 preNode
->mNext
= tNode
->mNext
;
1619 tNode
->mNext
= uNode
->mNext
;
1620 uNode
->mNext
= pNode
;
1622 // reset pNode to head list, scan the whole list again.
1624 pNode
= mIfrRecordListHead
;
1630 // not found form, continue scan IfrRecord list
1633 pNode
= tNode
->mNext
;
1642 pNode
= pNode
->mNext
;
1646 // Update Ifr Opcode Offset
1648 if (Status
== VFR_RETURN_SUCCESS
) {
1649 IfrAdjustOffsetForRecord ();
1655 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1656 given by expression, should save the default info for the Buffer VarStore.
1658 @param DefaultId The default id.
1659 @param pQuestionNode Point to the question opcode node.
1660 @param Value The default value.
1663 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1664 IN UINT16 DefaultId
,
1665 IN SIfrRecord
*pQuestionNode
,
1666 IN EFI_IFR_TYPE_VALUE Value
1669 CHAR8
*VarStoreName
= NULL
;
1670 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1671 EFI_GUID
*VarGuid
= NULL
;
1672 EFI_VARSTORE_INFO VarInfo
;
1673 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1674 EFI_IFR_OP_HEADER
*pQuestionOpHead
;
1676 pQuestionOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1677 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (pQuestionOpHead
+ 1);
1680 // Get the Var Store name and type.
1682 gCVfrDataStorage
.GetVarStoreName (QuestionHead
->VarStoreId
, &VarStoreName
);
1683 VarGuid
= gCVfrDataStorage
.GetVarStoreGuid (QuestionHead
->VarStoreId
);
1684 VarStoreType
= gCVfrDataStorage
.GetVarStoreType (QuestionHead
->VarStoreId
);
1687 // Only for Buffer storage need to save the default info in the storage.
1688 // Other type storage, just return.
1690 if (VarStoreType
!= EFI_VFR_VARSTORE_BUFFER
) {
1693 VarInfo
.mInfo
.mVarOffset
= QuestionHead
->VarStoreInfo
.VarOffset
;
1694 VarInfo
.mVarStoreId
= QuestionHead
->VarStoreId
;
1698 // Get the buffer storage info about this question.
1700 gCVfrDataStorage
.GetBufferVarStoreFieldInfo (&VarInfo
);
1705 gCVfrDefaultStore
.BufferVarStoreAltConfigAdd (
1716 Record the number and default id of all defaultstore opcode.
1720 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1725 EFI_IFR_OP_HEADER
*pOpHead
;
1726 EFI_IFR_DEFAULTSTORE
*DefaultStore
;
1728 pNode
= mIfrRecordListHead
;
1729 mAllDefaultTypeCount
= 0;
1731 while (pNode
!= NULL
) {
1732 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1734 if (pOpHead
->OpCode
== EFI_IFR_DEFAULTSTORE_OP
){
1735 DefaultStore
= (EFI_IFR_DEFAULTSTORE
*) pNode
->mIfrBinBuf
;
1736 mAllDefaultIdArray
[mAllDefaultTypeCount
++] = DefaultStore
->DefaultId
;
1738 pNode
= pNode
->mNext
;
1743 Create new default opcode record.
1745 @param Size The new default opcode size.
1746 @param DefaultId The new default id.
1747 @param Type The new default type.
1748 @param LineNo The line number of the new record.
1749 @param Value The new default value.
1753 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1755 IN UINT16 DefaultId
,
1758 IN EFI_IFR_TYPE_VALUE Value
1762 CIfrDefault2
*DObj2
;
1767 if (Type
== EFI_IFR_TYPE_OTHER
) {
1768 DObj2
= new CIfrDefault2 (Size
);
1769 DObj2
->SetDefaultId(DefaultId
);
1770 DObj2
->SetType(Type
);
1771 DObj2
->SetLineNo(LineNo
);
1772 DObj2
->SetScope (1);
1775 DObj
= new CIfrDefault (Size
);
1776 DObj
->SetDefaultId(DefaultId
);
1777 DObj
->SetType(Type
);
1778 DObj
->SetLineNo(LineNo
);
1779 DObj
->SetValue (Value
);
1785 Create new default opcode for question base on the QuestionDefaultInfo.
1787 @param pQuestionNode Point to the question opcode Node.
1788 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1792 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1793 IN SIfrRecord
*pQuestionNode
,
1794 IN QuestionDefaultRecord
*QuestionDefaultInfo
1797 EFI_IFR_OP_HEADER
*pOpHead
;
1798 EFI_IFR_DEFAULT
*Default
;
1801 SIfrRecord
*pDefaultNode
;
1808 EFI_IFR_ONE_OF_OPTION
*DefaultOptionOpcode
;
1809 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue
;
1811 CheckBoxDefaultValue
.b
= 1;
1812 pOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1818 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1820 gAdjustOpcodeOffset
= pQuestionNode
->mNext
->mOffset
;
1823 // For oneof, the default with smallest default id is given by the option flag.
1824 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1826 if (pOpHead
->OpCode
== EFI_IFR_ONE_OF_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1827 DefaultOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)QuestionDefaultInfo
->mDefaultValueRecord
->mIfrBinBuf
;
1828 DefaultSize
= QuestionDefaultInfo
->mDefaultValueRecord
->mBinBufLen
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
);
1829 DefaultSize
+= OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1830 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1831 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1832 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], DefaultOptionOpcode
->Type
, pQuestionNode
->mLineNo
, DefaultOptionOpcode
->Value
);
1834 // Save the new created default in the buffer storage.
1836 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, DefaultOptionOpcode
->Value
);
1844 // For checkbox, the default with smallest default id is given by the question flag.
1845 // And create the missing defaults with true value.
1847 if (pOpHead
-> OpCode
== EFI_IFR_CHECKBOX_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1848 DefaultSize
= OFFSET_OF (EFI_IFR_DEFAULT
, Value
) + sizeof (BOOLEAN
);
1849 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1850 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1851 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], EFI_IFR_TYPE_BOOLEAN
, pQuestionNode
->mLineNo
, CheckBoxDefaultValue
);
1853 // Save the new created default.
1855 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, CheckBoxDefaultValue
);
1863 // The default with smallest default id is given by the default opcode.
1864 // So create the missing defaults base on the value in the default opcode.
1868 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1870 pDefaultNode
= QuestionDefaultInfo
->mDefaultValueRecord
;
1871 Default
= (EFI_IFR_DEFAULT
*)pDefaultNode
->mIfrBinBuf
;
1873 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1875 gAdjustOpcodeOffset
= pDefaultNode
->mNext
->mOffset
;
1877 if (Default
->Type
== EFI_IFR_TYPE_OTHER
) {
1879 // EFI_IFR_DEFAULT_2 opcode.
1881 // Point to the first expression opcode.
1883 pSNode
= pDefaultNode
->mNext
;
1887 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1889 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& ScopeCount
!= 0) {
1890 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1891 if (pOpHead
->Scope
== 1) {
1894 if (pOpHead
->OpCode
== EFI_IFR_END_OP
) {
1898 pSNode
= pSNode
->mNext
;
1906 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1908 gAdjustOpcodeOffset
= pSNode
->mOffset
;
1910 // Create new default opcode node for missing default.
1912 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1913 OpcodeNumber
= OpcodeCount
;
1914 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1915 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pENode
->mLineNo
, Default
->Value
);
1917 // Point to the first expression opcode node.
1919 pSNode
= pDefaultNode
->mNext
;
1921 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1923 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& OpcodeNumber
-- != 0) {
1924 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1925 Obj
= new CIfrObj (pOpHead
->OpCode
, NULL
, pSNode
->mBinBufLen
, FALSE
);
1926 assert (Obj
!= NULL
);
1927 Obj
->SetLineNo (pSNode
->mLineNo
);
1928 ObjBinBuf
= Obj
->GetObjBinAddr
<CHAR8
>();
1929 memcpy (ObjBinBuf
, pSNode
->mIfrBinBuf
, (UINTN
)pSNode
->mBinBufLen
);
1931 pSNode
= pSNode
->mNext
;
1937 // EFI_IFR_DEFAULT opcode.
1939 // Create new default opcode node for missing default.
1941 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1942 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1943 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pDefaultNode
->mLineNo
, Default
->Value
);
1945 // Save the new created default in the buffer storage..
1947 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, Default
->Value
);
1954 Parse the default information in a question, get the QuestionDefaultInfo.
1956 @param pQuestionNode Point to the question record Node.
1957 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1960 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1961 IN SIfrRecord
*pQuestionNode
,
1962 OUT QuestionDefaultRecord
*QuestionDefaultInfo
1966 EFI_IFR_ONE_OF_OPTION
*OneofOptionOpcode
;
1967 EFI_IFR_OP_HEADER
*pSOpHead
;
1968 EFI_IFR_CHECKBOX
*CheckBoxOpcode
;
1969 EFI_IFR_DEFAULT
*DefaultOpcode
;
1970 BOOLEAN IsOneOfOpcode
;
1971 UINT16 SmallestDefaultId
;
1974 SmallestDefaultId
= 0xffff;
1975 IsOneOfOpcode
= FALSE
;
1977 pSNode
= pQuestionNode
;
1980 // Parse all the opcodes in the Question.
1982 while (pSNode
!= NULL
) {
1983 pSOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1985 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1986 // Scopes may be nested within other scopes.
1987 // When finishing parsing a question, the scope count must be zero.
1989 if (pSOpHead
->Scope
== 1) {
1992 if (pSOpHead
->OpCode
== EFI_IFR_END_OP
) {
1996 // Check whether finishing parsing a question.
1998 if (ScopeCount
== 0) {
2003 // Record the default information in the question.
2005 switch (pSOpHead
->OpCode
) {
2006 case EFI_IFR_ONE_OF_OP
:
2007 IsOneOfOpcode
= TRUE
;
2009 case EFI_IFR_CHECKBOX_OP
:
2011 // The default info of check box may be given by flag.
2012 // So need to check the flag of check box.
2014 CheckBoxOpcode
= (EFI_IFR_CHECKBOX
*)pSNode
->mIfrBinBuf
;
2015 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0) {
2017 // Check whether need to update the smallest default id.
2019 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2020 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2023 // Update the QuestionDefaultInfo.
2025 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2026 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2027 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2028 QuestionDefaultInfo
->mDefaultNumber
++;
2029 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2035 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0) {
2037 // Check whether need to update the smallest default id.
2039 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2040 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2043 // Update the QuestionDefaultInfo.
2045 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2046 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2047 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2048 QuestionDefaultInfo
->mDefaultNumber
++;
2049 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2056 case EFI_IFR_ONE_OF_OPTION_OP
:
2057 if (!IsOneOfOpcode
) {
2059 // Only check the option in oneof.
2063 OneofOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)pSNode
->mIfrBinBuf
;
2064 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2066 // The option is used as the standard default.
2067 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2069 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2070 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2071 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2074 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2076 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2077 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2078 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2079 QuestionDefaultInfo
->mDefaultNumber
++;
2080 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2086 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0) {
2088 // This option is used as the manufacture default.
2089 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2091 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2092 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2093 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2096 // Update the QuestionDefaultInfo.
2098 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2099 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2100 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2101 QuestionDefaultInfo
->mDefaultNumber
++;
2102 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2109 case EFI_IFR_DEFAULT_OP
:
2110 DefaultOpcode
= (EFI_IFR_DEFAULT
*) pSNode
->mIfrBinBuf
;
2112 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2114 if (SmallestDefaultId
>= DefaultOpcode
->DefaultId
) {
2115 SmallestDefaultId
= DefaultOpcode
->DefaultId
;
2116 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2117 QuestionDefaultInfo
->mIsDefaultOpcode
= TRUE
;
2120 // Update the QuestionDefaultInfo.
2122 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++){
2123 if (mAllDefaultIdArray
[i
] == ((EFI_IFR_DEFAULT
*)pSNode
->mIfrBinBuf
)->DefaultId
) {
2124 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2125 QuestionDefaultInfo
->mDefaultNumber
++;
2126 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2136 // Parse next opcode in this question.
2138 pSNode
= pSNode
->mNext
;
2143 Check or add default for question if need.
2145 This function will check the default info for question.
2146 If the question has default, but the default number < defaultstore opcode number.
2147 will do following two action :
2149 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2150 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2152 We assume that the two options can not be TRUE at same time.
2153 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2155 @param AutoDefault Add default for question if needed
2156 @param CheckDefault Check the default info, if missing default, generates an error.
2160 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2161 BOOLEAN AutoDefault
,
2162 BOOLEAN CheckDefault
2166 SIfrRecord
*pTailNode
;
2167 SIfrRecord
*pStartAdjustNode
;
2168 EFI_IFR_OP_HEADER
*pOpHead
;
2169 QuestionDefaultRecord QuestionDefaultInfo
;
2170 UINT8 MissingDefaultCount
;
2171 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
2173 pNode
= mIfrRecordListHead
;
2176 // Record the number and default id of all defaultstore opcode.
2178 IfrGetDefaultStoreInfo ();
2180 while (pNode
!= NULL
) {
2181 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
2183 // Check whether is question opcode.
2185 if (CheckQuestionOpCode (pOpHead
->OpCode
)) {
2187 // Initialize some local variables here, because they vary with question.
2188 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2190 memset (&QuestionDefaultInfo
, 0, sizeof (QuestionDefaultRecord
));
2191 pTailNode
= mIfrRecordListTail
;
2193 // Get the QuestionDefaultInfo for current question.
2195 IfrParseDefaulInfoInQuestion (pNode
, &QuestionDefaultInfo
);
2197 if (QuestionDefaultInfo
.mDefaultNumber
!= mAllDefaultTypeCount
&& QuestionDefaultInfo
.mDefaultNumber
!= 0) {
2200 // Create default for question which misses default.
2202 IfrCreateDefaultForQuestion (pNode
, &QuestionDefaultInfo
);
2205 // Adjust the buffer content.
2206 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2207 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2209 pStartAdjustNode
=GetRecordInfoFromOffset (gAdjustOpcodeOffset
);
2210 gCFormPkg
.AdjustDynamicInsertOpcode (pStartAdjustNode
->mIfrBinBuf
, pTailNode
->mNext
->mIfrBinBuf
, TRUE
);
2213 // Update the record info.
2215 IfrUpdateRecordInfoForDynamicOpcode (TRUE
);
2216 } else if (CheckDefault
) {
2218 // Generate an error for question which misses default.
2220 MissingDefaultCount
= mAllDefaultTypeCount
- QuestionDefaultInfo
.mDefaultNumber
;
2221 sprintf (Msg
, "The question misses %d default, the question's opcode is %d", MissingDefaultCount
, pOpHead
->OpCode
);
2222 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, NULL
, "Error", Msg
);
2227 // parse next opcode.
2229 pNode
= pNode
->mNext
;
2233 CIfrRecordInfoDB gCIfrRecordInfoDB
;
2236 CIfrObj::_EMIT_PENDING_OBJ (
2240 CHAR8
*ObjBinBuf
= NULL
;
2245 if (!mDelayEmit
|| !gCreateOp
) {
2249 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2251 // update data buffer to package data
2253 ObjBinBuf
= gCFormPkg
.IfrBinBufferGet (mObjBinLen
);
2254 if (ObjBinBuf
!= NULL
) {
2255 memmove (ObjBinBuf
, mObjBinBuf
, mObjBinLen
);
2259 // update bin buffer to package data buffer
2261 if (mObjBinBuf
!= NULL
) {
2262 delete[] mObjBinBuf
;
2263 mObjBinBuf
= ObjBinBuf
;
2270 * The definition of CIfrObj's member function
2275 } gOpcodeSizesScopeTable
[] = {
2276 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2277 { sizeof (EFI_IFR_FORM
), 1 }, // EFI_IFR_FORM_OP
2278 { sizeof (EFI_IFR_SUBTITLE
), 1 }, // EFI_IFR_SUBTITLE_OP
2279 { sizeof (EFI_IFR_TEXT
), 0 }, // EFI_IFR_TEXT_OP
2280 { sizeof (EFI_IFR_IMAGE
), 0 }, // EFI_IFR_IMAGE_OP
2281 { sizeof (EFI_IFR_ONE_OF
), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2282 { sizeof (EFI_IFR_CHECKBOX
), 1}, // EFI_IFR_CHECKBOX_OP
2283 { sizeof (EFI_IFR_NUMERIC
), 1 }, // EFI_IFR_NUMERIC_OP
2284 { sizeof (EFI_IFR_PASSWORD
), 1 }, // EFI_IFR_PASSWORD_OP
2285 { sizeof (EFI_IFR_ONE_OF_OPTION
), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2286 { sizeof (EFI_IFR_SUPPRESS_IF
), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2287 { sizeof (EFI_IFR_LOCKED
), 0 }, // EFI_IFR_LOCKED_OP
2288 { sizeof (EFI_IFR_ACTION
), 1 }, // EFI_IFR_ACTION_OP
2289 { sizeof (EFI_IFR_RESET_BUTTON
), 1 }, // EFI_IFR_RESET_BUTTON_OP
2290 { sizeof (EFI_IFR_FORM_SET
), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2291 { sizeof (EFI_IFR_REF
), 0 }, // EFI_IFR_REF_OP
2292 { sizeof (EFI_IFR_NO_SUBMIT_IF
), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2293 { sizeof (EFI_IFR_INCONSISTENT_IF
), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2294 { sizeof (EFI_IFR_EQ_ID_VAL
), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2295 { sizeof (EFI_IFR_EQ_ID_ID
), 0 }, // EFI_IFR_EQ_ID_ID_OP
2296 { sizeof (EFI_IFR_EQ_ID_VAL_LIST
), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2297 { sizeof (EFI_IFR_AND
), 0 }, // EFI_IFR_AND_OP
2298 { sizeof (EFI_IFR_OR
), 0 }, // EFI_IFR_OR_OP
2299 { sizeof (EFI_IFR_NOT
), 0 }, // EFI_IFR_NOT_OP
2300 { sizeof (EFI_IFR_RULE
), 1 }, // EFI_IFR_RULE_OP
2301 { sizeof (EFI_IFR_GRAY_OUT_IF
), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2302 { sizeof (EFI_IFR_DATE
), 1 }, // EFI_IFR_DATE_OP
2303 { sizeof (EFI_IFR_TIME
), 1 }, // EFI_IFR_TIME_OP
2304 { sizeof (EFI_IFR_STRING
), 1 }, // EFI_IFR_STRING_OP
2305 { sizeof (EFI_IFR_REFRESH
), 0 }, // EFI_IFR_REFRESH_OP
2306 { sizeof (EFI_IFR_DISABLE_IF
), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2308 { sizeof (EFI_IFR_TO_LOWER
), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2309 { sizeof (EFI_IFR_TO_UPPER
), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2310 { sizeof (EFI_IFR_MAP
), 1 }, // EFI_IFR_MAP - 0x22
2311 { sizeof (EFI_IFR_ORDERED_LIST
), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2312 { sizeof (EFI_IFR_VARSTORE
), 0 }, // EFI_IFR_VARSTORE_OP
2313 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE
), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2314 { sizeof (EFI_IFR_VARSTORE_EFI
), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2315 { sizeof (EFI_IFR_VARSTORE_DEVICE
), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2316 { sizeof (EFI_IFR_VERSION
), 0 }, // EFI_IFR_VERSION_OP - 0x28
2317 { sizeof (EFI_IFR_END
), 0 }, // EFI_IFR_END_OP
2318 { sizeof (EFI_IFR_MATCH
), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2319 { sizeof (EFI_IFR_GET
), 0 }, // EFI_IFR_GET - 0x2B
2320 { sizeof (EFI_IFR_SET
), 0 }, // EFI_IFR_SET - 0x2C
2321 { sizeof (EFI_IFR_READ
), 0 }, // EFI_IFR_READ - 0x2D
2322 { sizeof (EFI_IFR_WRITE
), 0 }, // EFI_IFR_WRITE - 0x2E
2323 { sizeof (EFI_IFR_EQUAL
), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2324 { sizeof (EFI_IFR_NOT_EQUAL
), 0 }, // EFI_IFR_NOT_EQUAL_OP
2325 { sizeof (EFI_IFR_GREATER_THAN
), 0 }, // EFI_IFR_GREATER_THAN_OP
2326 { sizeof (EFI_IFR_GREATER_EQUAL
), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2327 { sizeof (EFI_IFR_LESS_THAN
), 0 }, // EFI_IFR_LESS_THAN_OP
2328 { sizeof (EFI_IFR_LESS_EQUAL
), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2329 { sizeof (EFI_IFR_BITWISE_AND
), 0 }, // EFI_IFR_BITWISE_AND_OP
2330 { sizeof (EFI_IFR_BITWISE_OR
), 0 }, // EFI_IFR_BITWISE_OR_OP
2331 { sizeof (EFI_IFR_BITWISE_NOT
), 0 }, // EFI_IFR_BITWISE_NOT_OP
2332 { sizeof (EFI_IFR_SHIFT_LEFT
), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2333 { sizeof (EFI_IFR_SHIFT_RIGHT
), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2334 { sizeof (EFI_IFR_ADD
), 0 }, // EFI_IFR_ADD_OP - 0x3A
2335 { sizeof (EFI_IFR_SUBTRACT
), 0 }, // EFI_IFR_SUBTRACT_OP
2336 { sizeof (EFI_IFR_MULTIPLY
), 0 }, // EFI_IFR_MULTIPLY_OP
2337 { sizeof (EFI_IFR_DIVIDE
), 0 }, // EFI_IFR_DIVIDE_OP
2338 { sizeof (EFI_IFR_MODULO
), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2339 { sizeof (EFI_IFR_RULE_REF
), 0 }, // EFI_IFR_RULE_REF_OP
2340 { sizeof (EFI_IFR_QUESTION_REF1
), 0 }, // EFI_IFR_QUESTION_REF1_OP
2341 { sizeof (EFI_IFR_QUESTION_REF2
), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2342 { sizeof (EFI_IFR_UINT8
), 0}, // EFI_IFR_UINT8
2343 { sizeof (EFI_IFR_UINT16
), 0}, // EFI_IFR_UINT16
2344 { sizeof (EFI_IFR_UINT32
), 0}, // EFI_IFR_UINT32
2345 { sizeof (EFI_IFR_UINT64
), 0}, // EFI_IFR_UTNT64
2346 { sizeof (EFI_IFR_TRUE
), 0 }, // EFI_IFR_TRUE_OP - 0x46
2347 { sizeof (EFI_IFR_FALSE
), 0 }, // EFI_IFR_FALSE_OP
2348 { sizeof (EFI_IFR_TO_UINT
), 0 }, // EFI_IFR_TO_UINT_OP
2349 { sizeof (EFI_IFR_TO_STRING
), 0 }, // EFI_IFR_TO_STRING_OP
2350 { sizeof (EFI_IFR_TO_BOOLEAN
), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2351 { sizeof (EFI_IFR_MID
), 0 }, // EFI_IFR_MID_OP
2352 { sizeof (EFI_IFR_FIND
), 0 }, // EFI_IFR_FIND_OP
2353 { sizeof (EFI_IFR_TOKEN
), 0 }, // EFI_IFR_TOKEN_OP
2354 { sizeof (EFI_IFR_STRING_REF1
), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2355 { sizeof (EFI_IFR_STRING_REF2
), 0 }, // EFI_IFR_STRING_REF2_OP
2356 { sizeof (EFI_IFR_CONDITIONAL
), 0 }, // EFI_IFR_CONDITIONAL_OP
2357 { sizeof (EFI_IFR_QUESTION_REF3
), 0 }, // EFI_IFR_QUESTION_REF3_OP
2358 { sizeof (EFI_IFR_ZERO
), 0 }, // EFI_IFR_ZERO_OP
2359 { sizeof (EFI_IFR_ONE
), 0 }, // EFI_IFR_ONE_OP
2360 { sizeof (EFI_IFR_ONES
), 0 }, // EFI_IFR_ONES_OP
2361 { sizeof (EFI_IFR_UNDEFINED
), 0 }, // EFI_IFR_UNDEFINED_OP
2362 { sizeof (EFI_IFR_LENGTH
), 0 }, // EFI_IFR_LENGTH_OP
2363 { sizeof (EFI_IFR_DUP
), 0 }, // EFI_IFR_DUP_OP - 0x57
2364 { sizeof (EFI_IFR_THIS
), 0 }, // EFI_IFR_THIS_OP
2365 { sizeof (EFI_IFR_SPAN
), 0 }, // EFI_IFR_SPAN_OP
2366 { sizeof (EFI_IFR_VALUE
), 1 }, // EFI_IFR_VALUE_OP
2367 { sizeof (EFI_IFR_DEFAULT
), 0 }, // EFI_IFR_DEFAULT_OP
2368 { sizeof (EFI_IFR_DEFAULTSTORE
), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2369 { sizeof (EFI_IFR_FORM_MAP
), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2370 { sizeof (EFI_IFR_CATENATE
), 0 }, // EFI_IFR_CATENATE_OP
2371 { sizeof (EFI_IFR_GUID
), 0 }, // EFI_IFR_GUID_OP
2372 { sizeof (EFI_IFR_SECURITY
), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2373 { sizeof (EFI_IFR_MODAL_TAG
), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2374 { sizeof (EFI_IFR_REFRESH_ID
), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2375 { sizeof (EFI_IFR_WARNING_IF
), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2376 { sizeof (EFI_IFR_MATCH2
), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2379 #ifdef CIFROBJ_DEUBG
2382 } gIfrObjPrintDebugTable
[] = {
2383 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2384 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2385 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2386 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2387 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2388 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2389 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2390 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2391 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2392 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2393 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2394 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2395 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2396 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2397 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2398 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2399 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2403 CIFROBJ_DEBUG_PRINT (
2407 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable
[OpCode
].mIfrName
);
2411 #define CIFROBJ_DEBUG_PRINT(OpCode)
2415 BOOLEAN gCreateOp
= TRUE
;
2421 IN BOOLEAN DelayEmit
2424 mDelayEmit
= DelayEmit
;
2425 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2426 mObjBinLen
= (ObjBinLen
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: ObjBinLen
;
2427 mObjBinBuf
= ((DelayEmit
== FALSE
) && (gCreateOp
== TRUE
)) ? gCFormPkg
.IfrBinBufferGet (mObjBinLen
) : new CHAR8
[EFI_IFR_MAX_LENGTH
];
2428 mRecordIdx
= (gCreateOp
== TRUE
) ? gCIfrRecordInfoDB
.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf
, mObjBinLen
, mPkgOffset
) : EFI_IFR_RECORDINFO_IDX_INVALUD
;
2431 assert (mObjBinBuf
!= NULL
);
2433 if (IfrObj
!= NULL
) {
2434 *IfrObj
= mObjBinBuf
;
2437 CIFROBJ_DEBUG_PRINT (OpCode
);
2444 if ((mDelayEmit
== TRUE
) && ((gCreateOp
== TRUE
))) {
2445 _EMIT_PENDING_OBJ ();
2448 gCIfrRecordInfoDB
.IfrRecordInfoUpdate (mRecordIdx
, mLineNo
, mObjBinBuf
, mObjBinLen
, mPkgOffset
);
2452 * The definition of CIfrObj's member function
2454 UINT8 gScopeCount
= 0;
2456 CIfrOpHeader::CIfrOpHeader (
2460 ) : mHeader ((EFI_IFR_OP_HEADER
*)StartAddr
)
2462 mHeader
->OpCode
= OpCode
;
2463 mHeader
->Length
= (Length
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: Length
;
2464 mHeader
->Scope
= (gOpcodeSizesScopeTable
[OpCode
].mScope
+ gScopeCount
> 0) ? 1 : 0;
2467 CIfrOpHeader::CIfrOpHeader (
2468 IN CIfrOpHeader
&OpHdr
2471 mHeader
= OpHdr
.mHeader
;
2474 UINT32
CIfrFormId::FormIdBitMap
[EFI_FREE_FORM_ID_BITMAP_SIZE
] = {0, };