3 The definition of CFormPkg's member function
5 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "VfrFormPkg.h"
20 * The definition of CFormPkg's member function
23 SPendingAssign::SPendingAssign (
39 mKey
= new CHAR8
[strlen (Key
) + 1];
46 mMsg
= new CHAR8
[strlen (Msg
) + 1];
53 SPendingAssign::~SPendingAssign (
70 SPendingAssign::SetAddrAndLen (
80 SPendingAssign::AssignValue (
85 memmove (mAddr
, Addr
, (mLen
< Len
? mLen
: Len
));
90 SPendingAssign::GetKey (
106 mBufferNodeQueueHead
= NULL
;
107 mCurrBufferNode
= NULL
;
109 Node
= new SBufferNode
;
113 BufferStart
= new CHAR8
[BufferSize
];
114 if (BufferStart
== NULL
) {
117 BufferEnd
= BufferStart
+ BufferSize
;
119 memset (BufferStart
, 0, BufferSize
);
120 Node
->mBufferStart
= BufferStart
;
121 Node
->mBufferEnd
= BufferEnd
;
122 Node
->mBufferFree
= BufferStart
;
125 mBufferSize
= BufferSize
;
126 mBufferNodeQueueHead
= Node
;
127 mBufferNodeQueueTail
= Node
;
128 mCurrBufferNode
= Node
;
131 CFormPkg::~CFormPkg ()
134 SPendingAssign
*pPNode
;
136 while (mBufferNodeQueueHead
!= NULL
) {
137 pBNode
= mBufferNodeQueueHead
;
138 mBufferNodeQueueHead
= mBufferNodeQueueHead
->mNext
;
139 if (pBNode
->mBufferStart
!= NULL
) {
140 delete pBNode
->mBufferStart
;
144 mBufferNodeQueueTail
= NULL
;
145 mCurrBufferNode
= NULL
;
147 while (PendingAssignList
!= NULL
) {
148 pPNode
= PendingAssignList
;
149 PendingAssignList
= PendingAssignList
->mNext
;
152 PendingAssignList
= NULL
;
156 CFormPkg::CreateNewNode (
162 Node
= new SBufferNode
;
167 Node
->mBufferStart
= new CHAR8
[mBufferSize
];
168 if (Node
->mBufferStart
== NULL
) {
172 memset (Node
->mBufferStart
, 0, mBufferSize
);
173 Node
->mBufferEnd
= Node
->mBufferStart
+ mBufferSize
;
174 Node
->mBufferFree
= Node
->mBufferStart
;
182 CFormPkg::IfrBinBufferGet (
186 CHAR8
*BinBuffer
= NULL
;
187 SBufferNode
*Node
= NULL
;
189 if ((Len
== 0) || (Len
> mBufferSize
)) {
193 if ((mCurrBufferNode
->mBufferFree
+ Len
) <= mCurrBufferNode
->mBufferEnd
) {
194 BinBuffer
= mCurrBufferNode
->mBufferFree
;
195 mCurrBufferNode
->mBufferFree
+= Len
;
197 Node
= CreateNewNode ();
202 if (mBufferNodeQueueTail
== NULL
) {
203 mBufferNodeQueueHead
= mBufferNodeQueueTail
= Node
;
205 mBufferNodeQueueTail
->mNext
= Node
;
206 mBufferNodeQueueTail
= Node
;
208 mCurrBufferNode
= Node
;
213 BinBuffer
= mCurrBufferNode
->mBufferFree
;
214 mCurrBufferNode
->mBufferFree
+= Len
;
224 CFormPkg::GetPkgLength (
236 mReadBufferNode
= mBufferNodeQueueHead
;
237 mReadBufferOffset
= 0;
245 mReadBufferNode
= NULL
;
246 mReadBufferOffset
= 0;
257 if ((Size
== 0) || (Buffer
== NULL
)) {
261 if (mReadBufferNode
== NULL
) {
265 for (Index
= 0; Index
< Size
; Index
++) {
266 if ((mReadBufferNode
->mBufferStart
+ mReadBufferOffset
) < mReadBufferNode
->mBufferFree
) {
267 Buffer
[Index
] = mReadBufferNode
->mBufferStart
[mReadBufferOffset
++];
269 if ((mReadBufferNode
= mReadBufferNode
->mNext
) == NULL
) {
272 mReadBufferOffset
= 0;
282 CFormPkg::BuildPkgHdr (
283 OUT EFI_HII_PACKAGE_HEADER
**PkgHdr
286 if (PkgHdr
== NULL
) {
287 return VFR_RETURN_FATAL_ERROR
;
290 if (((*PkgHdr
) = new EFI_HII_PACKAGE_HEADER
) == NULL
) {
291 return VFR_RETURN_OUT_FOR_RESOURCES
;
294 (*PkgHdr
)->Type
= EFI_HII_PACKAGE_FORM
;
295 (*PkgHdr
)->Length
= mPkgLength
+ sizeof (EFI_HII_PACKAGE_HEADER
);
297 return VFR_RETURN_SUCCESS
;
302 OUT PACKAGE_DATA
&TBuffer
310 if (TBuffer
.Buffer
!= NULL
) {
311 delete TBuffer
.Buffer
;
314 TBuffer
.Size
= mPkgLength
;
315 TBuffer
.Buffer
= NULL
;
316 if (TBuffer
.Size
!= 0) {
317 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
319 return VFR_RETURN_SUCCESS
;
322 Temp
= TBuffer
.Buffer
;
324 while ((Size
= Read (Buffer
, 1024)) != 0) {
325 memcpy (Temp
, Buffer
, Size
);
329 return VFR_RETURN_SUCCESS
;
336 IN PACKAGE_DATA
*PkgData
339 EFI_VFR_RETURN_CODE Ret
;
342 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
344 if (Output
== NULL
) {
345 return VFR_RETURN_FATAL_ERROR
;
348 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
351 fwrite (PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
), 1, Output
);
354 if (PkgData
== NULL
) {
356 while ((Size
= Read (Buffer
, 1024)) != 0) {
357 fwrite (Buffer
, Size
, 1, Output
);
361 fwrite (PkgData
->Buffer
, PkgData
->Size
, 1, Output
);
364 return VFR_RETURN_SUCCESS
;
368 CFormPkg::_WRITE_PKG_LINE (
371 IN CONST CHAR8
*LineHeader
,
378 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
382 for (Index
= 0; Index
< BlkSize
; Index
++) {
383 if ((Index
% LineBytes
) == 0) {
384 fprintf (pFile
, "\n%s", LineHeader
);
386 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
391 CFormPkg::_WRITE_PKG_END (
394 IN CONST CHAR8
*LineHeader
,
401 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
405 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
406 if ((Index
% LineBytes
) == 0) {
407 fprintf (pFile
, "\n%s", LineHeader
);
409 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
412 if ((Index
% LineBytes
) == 0) {
413 fprintf (pFile
, "\n%s", LineHeader
);
415 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
418 #define BYTES_PRE_LINE 0x10
419 UINT32 gAdjustOpcodeOffset
= 0;
420 BOOLEAN gNeedAdjustOpcode
= FALSE
;
421 UINT32 gAdjustOpcodeLen
= 0;
427 IN PACKAGE_DATA
*PkgData
430 EFI_VFR_RETURN_CODE Ret
;
431 CHAR8 Buffer
[BYTES_PRE_LINE
* 8];
432 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
433 UINT32 PkgLength
= 0;
436 if ((BaseName
== NULL
) || (pFile
== NULL
)) {
437 return VFR_RETURN_FATAL_ERROR
;
440 fprintf (pFile
, "\nunsigned char %sBin[] = {\n", BaseName
);
442 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
447 // For framework vfr file, the extension framework header will be added.
449 if (VfrCompatibleMode
) {
450 fprintf (pFile
, " // FRAMEWORK PACKAGE HEADER Length\n");
451 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
) + 2;
452 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
453 fprintf (pFile
, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
455 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT16
));
457 fprintf (pFile
, " // ARRAY LENGTH\n");
458 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
);
459 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
462 fprintf (pFile
, "\n\n // PACKAGE HEADER\n");
463 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
464 PkgLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
466 fprintf (pFile
, "\n\n // PACKAGE DATA\n");
468 if (PkgData
== NULL
) {
470 while ((ReadSize
= Read ((CHAR8
*)Buffer
, BYTES_PRE_LINE
* 8)) != 0) {
471 PkgLength
+= ReadSize
;
472 if (PkgLength
< PkgHdr
->Length
) {
473 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
475 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
480 if (PkgData
->Size
% BYTES_PRE_LINE
!= 0) {
481 PkgLength
= PkgData
->Size
- (PkgData
->Size
% BYTES_PRE_LINE
);
482 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
483 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, PkgData
->Size
% BYTES_PRE_LINE
);
485 PkgLength
= PkgData
->Size
- BYTES_PRE_LINE
;
486 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
487 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, BYTES_PRE_LINE
);
492 fprintf (pFile
, "\n};\n");
494 return VFR_RETURN_SUCCESS
;
498 CFormPkg::AssignPending (
506 SPendingAssign
*pNew
;
508 pNew
= new SPendingAssign (Key
, ValAddr
, ValLen
, LineNo
, Msg
);
510 return VFR_RETURN_OUT_FOR_RESOURCES
;
513 pNew
->mNext
= PendingAssignList
;
514 PendingAssignList
= pNew
;
515 return VFR_RETURN_SUCCESS
;
519 CFormPkg::DoPendingAssign (
525 SPendingAssign
*pNode
;
527 if ((Key
== NULL
) || (ValAddr
== NULL
)) {
531 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
532 if (strcmp (pNode
->mKey
, Key
) == 0) {
533 pNode
->AssignValue (ValAddr
, ValLen
);
539 CFormPkg::HavePendingUnassigned (
543 SPendingAssign
*pNode
;
545 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
546 if (pNode
->mFlag
== PENDING
) {
555 CFormPkg::PendingAssignPrintAll (
559 SPendingAssign
*pNode
;
561 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
562 if (pNode
->mFlag
== PENDING
) {
563 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", pNode
->mMsg
);
569 CFormPkg::GetBinBufferNodeForAddr (
570 IN CHAR8
*BinBuffAddr
573 SBufferNode
*TmpNode
;
575 TmpNode
= mBufferNodeQueueHead
;
577 while (TmpNode
!= NULL
) {
578 if (TmpNode
->mBufferStart
<= BinBuffAddr
&& TmpNode
->mBufferFree
>= BinBuffAddr
) {
582 TmpNode
= TmpNode
->mNext
;
589 CFormPkg::GetNodeBefore(
590 IN SBufferNode
*CurrentNode
593 SBufferNode
*FirstNode
= mBufferNodeQueueHead
;
594 SBufferNode
*LastNode
= mBufferNodeQueueHead
;
596 while (FirstNode
!= NULL
) {
597 if (FirstNode
== CurrentNode
) {
601 LastNode
= FirstNode
;
602 FirstNode
= FirstNode
->mNext
;
605 if (FirstNode
== NULL
) {
613 CFormPkg::InsertNodeBefore(
614 IN SBufferNode
*CurrentNode
,
615 IN SBufferNode
*NewNode
618 SBufferNode
*LastNode
= GetNodeBefore (CurrentNode
);
620 if (LastNode
== NULL
) {
621 return VFR_RETURN_MISMATCHED
;
624 NewNode
->mNext
= LastNode
->mNext
;
625 LastNode
->mNext
= NewNode
;
627 return VFR_RETURN_SUCCESS
;
631 CFormPkg::GetBufAddrBaseOnOffset (
635 SBufferNode
*TmpNode
;
637 UINT32 CurrentBufLen
;
641 for (TmpNode
= mBufferNodeQueueHead
; TmpNode
!= NULL
; TmpNode
= TmpNode
->mNext
) {
642 CurrentBufLen
= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
643 if (Offset
>= TotalBufLen
&& Offset
< TotalBufLen
+ CurrentBufLen
) {
644 return TmpNode
->mBufferStart
+ (Offset
- TotalBufLen
);
647 TotalBufLen
+= CurrentBufLen
;
654 CFormPkg::AdjustDynamicInsertOpcode (
655 IN CHAR8
*LastFormEndAddr
,
656 IN CHAR8
*InsertOpcodeAddr
659 SBufferNode
*LastFormEndNode
;
660 SBufferNode
*InsertOpcodeNode
;
661 SBufferNode
*NewRestoreNodeBegin
;
662 SBufferNode
*NewRestoreNodeEnd
;
663 SBufferNode
*NewLastEndNode
;
664 SBufferNode
*TmpNode
;
665 UINT32 NeedRestoreCodeLen
;
667 NewRestoreNodeEnd
= NULL
;
669 LastFormEndNode
= GetBinBufferNodeForAddr(LastFormEndAddr
);
670 InsertOpcodeNode
= GetBinBufferNodeForAddr(InsertOpcodeAddr
);
672 if (LastFormEndNode
== InsertOpcodeNode
) {
674 // Create New Node to save the restore opcode.
676 NeedRestoreCodeLen
= InsertOpcodeAddr
- LastFormEndAddr
;
677 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
678 NewRestoreNodeBegin
= CreateNewNode ();
679 if (NewRestoreNodeBegin
== NULL
) {
680 return VFR_RETURN_OUT_FOR_RESOURCES
;
682 memcpy (NewRestoreNodeBegin
->mBufferFree
, LastFormEndAddr
, NeedRestoreCodeLen
);
683 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
686 // Override the restore buffer data.
688 memmove (LastFormEndAddr
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
689 InsertOpcodeNode
->mBufferFree
-= NeedRestoreCodeLen
;
690 memset (InsertOpcodeNode
->mBufferFree
, 0, NeedRestoreCodeLen
);
693 // Create New Node to save the restore opcode.
695 NeedRestoreCodeLen
= LastFormEndNode
->mBufferFree
- LastFormEndAddr
;
696 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
697 NewRestoreNodeBegin
= CreateNewNode ();
698 if (NewRestoreNodeBegin
== NULL
) {
699 return VFR_RETURN_OUT_FOR_RESOURCES
;
701 memcpy (NewRestoreNodeBegin
->mBufferFree
, LastFormEndAddr
, NeedRestoreCodeLen
);
702 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
704 // Override the restore buffer data.
706 LastFormEndNode
->mBufferFree
-= NeedRestoreCodeLen
;
708 // Link the restore data to new node.
710 NewRestoreNodeBegin
->mNext
= LastFormEndNode
->mNext
;
713 // Count the Adjust opcode len.
715 TmpNode
= LastFormEndNode
->mNext
;
716 while (TmpNode
!= InsertOpcodeNode
) {
717 gAdjustOpcodeLen
+= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
718 TmpNode
= TmpNode
->mNext
;
722 // Create New Node to save the last node of restore opcode.
724 NeedRestoreCodeLen
= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
725 gAdjustOpcodeLen
+= NeedRestoreCodeLen
;
726 if (NeedRestoreCodeLen
> 0) {
727 NewRestoreNodeEnd
= CreateNewNode ();
728 if (NewRestoreNodeEnd
== NULL
) {
729 return VFR_RETURN_OUT_FOR_RESOURCES
;
731 memcpy (NewRestoreNodeEnd
->mBufferFree
, InsertOpcodeNode
->mBufferStart
, NeedRestoreCodeLen
);
732 NewRestoreNodeEnd
->mBufferFree
+= NeedRestoreCodeLen
;
734 // Override the restore buffer data.
736 memmove (InsertOpcodeNode
->mBufferStart
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
737 InsertOpcodeNode
->mBufferFree
-= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
740 // Insert the last restore data node.
742 TmpNode
= GetNodeBefore (InsertOpcodeNode
);
743 if (TmpNode
== LastFormEndNode
) {
744 NewRestoreNodeBegin
->mNext
= NewRestoreNodeEnd
;
746 TmpNode
->mNext
= NewRestoreNodeEnd
;
749 // Connect the dynamic opcode node to the node before last form end node.
751 LastFormEndNode
->mNext
= InsertOpcodeNode
;
755 if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
> 2) {
757 // End form set opcode all in the mBufferNodeQueueTail node.
759 NewLastEndNode
= CreateNewNode ();
760 if (NewLastEndNode
== NULL
) {
761 return VFR_RETURN_OUT_FOR_RESOURCES
;
763 NewLastEndNode
->mBufferStart
[0] = 0x29;
764 NewLastEndNode
->mBufferStart
[1] = 0x02;
765 NewLastEndNode
->mBufferFree
+= 2;
767 mBufferNodeQueueTail
->mBufferFree
-= 2;
769 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
770 if (NewRestoreNodeEnd
!= NULL
) {
771 NewRestoreNodeEnd
->mNext
= NewLastEndNode
;
773 NewRestoreNodeBegin
->mNext
= NewLastEndNode
;
776 mBufferNodeQueueTail
= NewLastEndNode
;
777 } else if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
== 2) {
778 TmpNode
= GetNodeBefore(mBufferNodeQueueTail
);
779 TmpNode
->mNext
= NewRestoreNodeBegin
;
780 if (NewRestoreNodeEnd
!= NULL
) {
781 NewRestoreNodeEnd
->mNext
= mBufferNodeQueueTail
;
783 NewRestoreNodeBegin
->mNext
= mBufferNodeQueueTail
;
787 return VFR_RETURN_SUCCESS
;
791 CFormPkg::DeclarePendingQuestion (
792 IN CVfrVarDataTypeDB
&lCVfrVarDataTypeDB
,
793 IN CVfrDataStorage
&lCVfrDataStorage
,
794 IN CVfrQuestionDB
&lCVfrQuestionDB
,
795 IN EFI_GUID
*LocalFormSetGuid
,
797 OUT CHAR8
**InsertOpcodeAddr
800 SPendingAssign
*pNode
;
803 CHAR8 FName
[MAX_NAME_LEN
];
807 EFI_VFR_RETURN_CODE ReturnCode
;
808 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
809 EFI_VARSTORE_ID VarStoreId
= EFI_VARSTORE_ID_INVALID
;
812 // Declare all questions as Numeric in DisableIf True
816 DIObj
.SetLineNo (LineNo
);
817 *InsertOpcodeAddr
= DIObj
.GetObjBinAddr ();
820 CIfrTrue
TObj (LineNo
);
822 // Declare Numeric qeustion for each undefined question.
823 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
824 if (pNode
->mFlag
== PENDING
) {
826 EFI_VARSTORE_INFO Info
;
827 EFI_QUESTION_ID QId
= EFI_QUESTION_ID_INVALID
;
829 CNObj
.SetLineNo (LineNo
);
830 CNObj
.SetPrompt (0x0);
834 // Register this question, assume it is normal question, not date or time question
836 VarStr
= pNode
->mKey
;
837 ReturnCode
= lCVfrQuestionDB
.RegisterQuestion (NULL
, VarStr
, QId
);
838 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
839 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
844 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr
, QId
);
847 // Get Question Info, framework vfr VarName == StructName
849 ReturnCode
= lCVfrVarDataTypeDB
.ExtractFieldNameAndArrary (VarStr
, FName
, ArrayIdx
);
850 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
851 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", "Var string is not the valid C variable");
857 ReturnCode
= lCVfrDataStorage
.GetVarStoreId (FName
, &Info
.mVarStoreId
);
858 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
859 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, FName
, "Error", "Var Store Type is not defined");
862 VarStoreType
= lCVfrDataStorage
.GetVarStoreType (Info
.mVarStoreId
);
864 if (*VarStr
== '\0' && ArrayIdx
!= INVALID_ARRAY_INDEX
) {
865 ReturnCode
= lCVfrDataStorage
.GetNameVarStoreInfo (&Info
, ArrayIdx
);
867 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
868 ReturnCode
= lCVfrDataStorage
.GetEfiVarStoreInfo (&Info
);
869 } else if (VarStoreType
== EFI_VFR_VARSTORE_BUFFER
) {
870 VarStr
= pNode
->mKey
;
871 //convert VarStr with store name to VarStr with structure name
872 ReturnCode
= lCVfrDataStorage
.GetBufferVarStoreDataTypeName (Info
.mVarStoreId
, &SName
);
873 if (ReturnCode
== VFR_RETURN_SUCCESS
) {
874 NewStr
= new CHAR8
[strlen (VarStr
) + strlen (SName
) + 1];
876 strcpy (NewStr
, SName
);
877 strcat (NewStr
, VarStr
+ strlen (FName
));
878 ReturnCode
= lCVfrVarDataTypeDB
.GetDataFieldInfo (NewStr
, Info
.mInfo
.mVarOffset
, Info
.mVarType
, Info
.mVarTotalSize
);
882 ReturnCode
= VFR_RETURN_UNSUPPORTED
;
885 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
886 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
890 CNObj
.SetQuestionId (QId
);
891 CNObj
.SetVarStoreInfo (&Info
);
893 // Numeric doesn't support BOOLEAN data type.
894 // BOOLEAN type has the same data size to UINT8.
896 if (Info
.mVarType
== EFI_IFR_TYPE_BOOLEAN
) {
897 Info
.mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
899 CNObj
.SetFlags (0, Info
.mVarType
);
901 // Use maximum value not to limit the vaild value for the undefined question.
903 switch (Info
.mVarType
) {
904 case EFI_IFR_TYPE_NUM_SIZE_64
:
905 CNObj
.SetMinMaxStepData ((UINT64
) 0, (UINT64
) -1 , (UINT64
) 0);
908 case EFI_IFR_TYPE_NUM_SIZE_32
:
909 CNObj
.SetMinMaxStepData ((UINT32
) 0, (UINT32
) -1 , (UINT32
) 0);
912 case EFI_IFR_TYPE_NUM_SIZE_16
:
913 CNObj
.SetMinMaxStepData ((UINT16
) 0, (UINT16
) -1 , (UINT16
) 0);
916 case EFI_IFR_TYPE_NUM_SIZE_8
:
917 CNObj
.SetMinMaxStepData ((UINT8
) 0, (UINT8
) -1 , (UINT8
) 0);
923 CNObj
.ShrinkBinSize (ShrinkSize
);
926 // For undefined Efi VarStore type question
927 // Append the extended guided opcode to contain VarName
929 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
|| VfrCompatibleMode
) {
930 CIfrVarEqName
CVNObj (QId
, Info
.mInfo
.mVarName
);
931 CVNObj
.SetLineNo (LineNo
);
938 CEObj
.SetLineNo (LineNo
);
946 SEObj
.SetLineNo (LineNo
);
948 return VFR_RETURN_SUCCESS
;
953 SIfrRecord::SIfrRecord (
959 mLineNo
= 0xFFFFFFFF;
960 mOffset
= 0xFFFFFFFF;
964 SIfrRecord::~SIfrRecord (
968 if (mIfrBinBuf
!= NULL
) {
972 mLineNo
= 0xFFFFFFFF;
973 mOffset
= 0xFFFFFFFF;
978 CIfrRecordInfoDB::CIfrRecordInfoDB (
983 mRecordCount
= EFI_IFR_RECORDINFO_IDX_START
;
984 mIfrRecordListHead
= NULL
;
985 mIfrRecordListTail
= NULL
;
988 CIfrRecordInfoDB::~CIfrRecordInfoDB (
994 while (mIfrRecordListHead
!= NULL
) {
995 pNode
= mIfrRecordListHead
;
996 mIfrRecordListHead
= mIfrRecordListHead
->mNext
;
1002 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1007 SIfrRecord
*pNode
= NULL
;
1009 if (RecordIdx
== EFI_IFR_RECORDINFO_IDX_INVALUD
) {
1013 for (Idx
= (EFI_IFR_RECORDINFO_IDX_START
+ 1), pNode
= mIfrRecordListHead
;
1014 (Idx
!= RecordIdx
) && (pNode
!= NULL
);
1015 Idx
++, pNode
= pNode
->mNext
)
1022 CIfrRecordInfoDB::IfrRecordRegister (
1024 IN CHAR8
*IfrBinBuf
,
1031 if (mSwitch
== FALSE
) {
1032 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1035 if ((pNew
= new SIfrRecord
) == NULL
) {
1036 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1039 if (mIfrRecordListHead
== NULL
) {
1040 mIfrRecordListHead
= pNew
;
1041 mIfrRecordListTail
= pNew
;
1043 mIfrRecordListTail
->mNext
= pNew
;
1044 mIfrRecordListTail
= pNew
;
1048 return mRecordCount
;
1052 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1053 IN UINT32 RecordIdx
,
1063 if ((pNode
= GetRecordInfoFromIdx (RecordIdx
)) == NULL
) {
1069 // Line number is not specified explicitly, try to use line number of previous opcode
1071 Prev
= GetRecordInfoFromIdx (RecordIdx
- 1);
1073 LineNo
= Prev
->mLineNo
;
1077 pNode
->mLineNo
= LineNo
;
1078 pNode
->mOffset
= Offset
;
1079 pNode
->mBinBufLen
= BinBufLen
;
1080 pNode
->mIfrBinBuf
= BinBuf
;
1085 CIfrRecordInfoDB::IfrRecordOutput (
1086 OUT PACKAGE_DATA
&TBuffer
1092 if (TBuffer
.Buffer
!= NULL
) {
1093 delete TBuffer
.Buffer
;
1097 TBuffer
.Buffer
= NULL
;
1100 if (mSwitch
== FALSE
) {
1104 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1105 TBuffer
.Size
+= pNode
->mBinBufLen
;
1108 if (TBuffer
.Size
!= 0) {
1109 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
1114 Temp
= TBuffer
.Buffer
;
1116 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1117 if (pNode
->mIfrBinBuf
!= NULL
) {
1118 memcpy (Temp
, pNode
->mIfrBinBuf
, pNode
->mBinBufLen
);
1119 Temp
+= pNode
->mBinBufLen
;
1127 CIfrRecordInfoDB::IfrRecordOutput (
1136 if (mSwitch
== FALSE
) {
1146 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1147 if (pNode
->mLineNo
== LineNo
|| LineNo
== 0) {
1148 fprintf (File
, ">%08X: ", pNode
->mOffset
);
1149 TotalSize
+= pNode
->mBinBufLen
;
1150 if (pNode
->mIfrBinBuf
!= NULL
) {
1151 for (Index
= 0; Index
< pNode
->mBinBufLen
; Index
++) {
1152 fprintf (File
, "%02X ", (UINT8
)(pNode
->mIfrBinBuf
[Index
]));
1155 fprintf (File
, "\n");
1160 fprintf (File
, "\nTotal Size of all record is 0x%08X\n", TotalSize
);
1165 // for framework vfr file
1166 // adjust opcode sequence for uefi IFR format
1167 // adjust inconsistent and varstore into the right position.
1170 CIfrRecordInfoDB::CheckQuestionOpCode (
1175 case EFI_IFR_CHECKBOX_OP
:
1176 case EFI_IFR_NUMERIC_OP
:
1177 case EFI_IFR_PASSWORD_OP
:
1178 case EFI_IFR_ONE_OF_OP
:
1179 case EFI_IFR_ACTION_OP
:
1180 case EFI_IFR_STRING_OP
:
1181 case EFI_IFR_DATE_OP
:
1182 case EFI_IFR_TIME_OP
:
1183 case EFI_IFR_ORDERED_LIST_OP
:
1191 CIfrRecordInfoDB::CheckIdOpCode (
1196 case EFI_IFR_EQ_ID_VAL_OP
:
1197 case EFI_IFR_EQ_ID_ID_OP
:
1198 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1199 case EFI_IFR_QUESTION_REF1_OP
:
1207 CIfrRecordInfoDB::GetOpcodeQuestionId (
1208 IN EFI_IFR_OP_HEADER
*OpHead
1211 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1213 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (OpHead
+ 1);
1215 return QuestionHead
->QuestionId
;
1219 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1223 SIfrRecord
*pNode
= NULL
;
1225 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1226 if (pNode
->mOffset
== Offset
) {
1235 Add just the op code position.
1239 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |
1243 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |
1247 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1251 UINT32 OpcodeOffset
;
1252 SIfrRecord
*pNode
, *pPreNode
;
1253 SIfrRecord
*pStartNode
, *pNodeBeforeStart
;
1254 SIfrRecord
*pEndNode
;
1261 // Base on the offset info to get the node.
1263 for (pNode
= mIfrRecordListHead
; pNode
->mNext
!= NULL
; pPreNode
= pNode
,pNode
= pNode
->mNext
) {
1264 if (OpcodeOffset
== gAdjustOpcodeOffset
) {
1266 pNodeBeforeStart
= pPreNode
;
1267 } else if (OpcodeOffset
== gAdjustOpcodeOffset
+ gAdjustOpcodeLen
) {
1268 pEndNode
= pPreNode
;
1271 OpcodeOffset
+= pNode
->mBinBufLen
;
1277 if (pEndNode
== NULL
|| pStartNode
== NULL
) {
1282 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1284 pNodeBeforeStart
->mNext
= pEndNode
->mNext
;
1285 pPreNode
->mNext
= pStartNode
;
1286 pEndNode
->mNext
= mIfrRecordListTail
;
1292 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1296 UINT32 OpcodeOffset
;
1300 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1301 pNode
->mOffset
= OpcodeOffset
;
1302 OpcodeOffset
+= pNode
->mBinBufLen
;
1307 CIfrRecordInfoDB::IfrRecordAdjust (
1311 SIfrRecord
*pNode
, *preNode
;
1312 SIfrRecord
*uNode
, *tNode
;
1313 EFI_IFR_OP_HEADER
*OpHead
, *tOpHead
;
1314 EFI_QUESTION_ID QuestionId
;
1316 UINT32 QuestionScope
;
1317 UINT32 OpcodeOffset
;
1318 CHAR8 ErrorMsg
[MAX_STRING_LEN
] = {0, };
1319 EFI_VFR_RETURN_CODE Status
;
1322 // Init local variable
1324 Status
= VFR_RETURN_SUCCESS
;
1325 pNode
= mIfrRecordListHead
;
1328 while (pNode
!= NULL
) {
1329 OpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1332 // make sure the inconsistent opcode in question scope
1334 if (QuestionScope
> 0) {
1335 QuestionScope
+= OpHead
->Scope
;
1336 if (OpHead
->OpCode
== EFI_IFR_END_OP
) {
1341 if (CheckQuestionOpCode (OpHead
->OpCode
)) {
1345 // for the inconsistent opcode not in question scope, adjust it
1347 if (OpHead
->OpCode
== EFI_IFR_INCONSISTENT_IF_OP
&& QuestionScope
== 0) {
1349 // for inconsistent opcode not in question scope
1353 // Count inconsistent opcode Scope
1355 StackCount
= OpHead
->Scope
;
1356 QuestionId
= EFI_QUESTION_ID_INVALID
;
1358 while (tNode
!= NULL
&& StackCount
> 0) {
1359 tNode
= tNode
->mNext
;
1360 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mIfrBinBuf
;
1362 // Calculate Scope Number
1364 StackCount
+= tOpHead
->Scope
;
1365 if (tOpHead
->OpCode
== EFI_IFR_END_OP
) {
1369 // by IdEqual opcode to get QuestionId
1371 if (QuestionId
== EFI_QUESTION_ID_INVALID
&&
1372 CheckIdOpCode (tOpHead
->OpCode
)) {
1373 QuestionId
= *(EFI_QUESTION_ID
*) (tOpHead
+ 1);
1376 if (tNode
== NULL
|| QuestionId
== EFI_QUESTION_ID_INVALID
) {
1378 // report error; not found
1380 sprintf (ErrorMsg
, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId
);
1381 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1382 Status
= VFR_RETURN_MISMATCHED
;
1386 // extract inconsistent opcode list
1387 // pNode is Incosistent opcode, tNode is End Opcode
1391 // insert inconsistent opcode list into the right question scope by questionid
1393 for (uNode
= mIfrRecordListHead
; uNode
!= NULL
; uNode
= uNode
->mNext
) {
1394 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mIfrBinBuf
;
1395 if (CheckQuestionOpCode (tOpHead
->OpCode
) &&
1396 (QuestionId
== GetOpcodeQuestionId (tOpHead
))) {
1401 // insert inconsistent opcode list and check LATE_CHECK flag
1403 if (uNode
!= NULL
) {
1404 if ((((EFI_IFR_QUESTION_HEADER
*)(tOpHead
+ 1))->Flags
& 0x20) != 0) {
1406 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1408 OpHead
->OpCode
= EFI_IFR_NO_SUBMIT_IF_OP
;
1412 // skip the default storage for Date and Time
1414 if ((uNode
->mNext
!= NULL
) && (*uNode
->mNext
->mIfrBinBuf
== EFI_IFR_DEFAULT_OP
)) {
1415 uNode
= uNode
->mNext
;
1418 preNode
->mNext
= tNode
->mNext
;
1419 tNode
->mNext
= uNode
->mNext
;
1420 uNode
->mNext
= pNode
;
1422 // reset pNode to head list, scan the whole list again.
1424 pNode
= mIfrRecordListHead
;
1430 // not found matched question id, report error
1432 sprintf (ErrorMsg
, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId
);
1433 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1434 Status
= VFR_RETURN_MISMATCHED
;
1437 } else if (OpHead
->OpCode
== EFI_IFR_VARSTORE_OP
||
1438 OpHead
->OpCode
== EFI_IFR_VARSTORE_EFI_OP
) {
1440 // for new added group of varstore opcode
1443 while (tNode
->mNext
!= NULL
) {
1444 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mNext
->mIfrBinBuf
;
1445 if (tOpHead
->OpCode
!= EFI_IFR_VARSTORE_OP
&&
1446 tOpHead
->OpCode
!= EFI_IFR_VARSTORE_EFI_OP
) {
1449 tNode
= tNode
->mNext
;
1452 if (tNode
->mNext
== NULL
) {
1454 // invalid IfrCode, IfrCode end by EndOpCode
1456 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", "No found End Opcode in the end");
1457 Status
= VFR_RETURN_MISMATCHED
;
1461 if (tOpHead
->OpCode
!= EFI_IFR_END_OP
) {
1463 // not new added varstore, which are not needed to be adjust.
1466 pNode
= tNode
->mNext
;
1470 // move new added varstore opcode to the position befor form opcode
1471 // varstore opcode between pNode and tNode
1475 // search form opcode from begin
1477 for (uNode
= mIfrRecordListHead
; uNode
->mNext
!= NULL
; uNode
= uNode
->mNext
) {
1478 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mNext
->mIfrBinBuf
;
1479 if (tOpHead
->OpCode
== EFI_IFR_FORM_OP
) {
1484 // Insert varstore opcode beform form opcode if form opcode is found
1486 if (uNode
->mNext
!= NULL
) {
1487 preNode
->mNext
= tNode
->mNext
;
1488 tNode
->mNext
= uNode
->mNext
;
1489 uNode
->mNext
= pNode
;
1491 // reset pNode to head list, scan the whole list again.
1493 pNode
= mIfrRecordListHead
;
1499 // not found form, continue scan IfrRecord list
1502 pNode
= tNode
->mNext
;
1511 pNode
= pNode
->mNext
;
1515 // Update Ifr Opcode Offset
1517 if (Status
== VFR_RETURN_SUCCESS
) {
1518 IfrAdjustOffsetForRecord ();
1523 CIfrRecordInfoDB gCIfrRecordInfoDB
;
1526 CIfrObj::_EMIT_PENDING_OBJ (
1530 CHAR8
*ObjBinBuf
= NULL
;
1535 if (!mDelayEmit
|| !gCreateOp
) {
1539 mPkgOffset
= gCFormPkg
.GetPkgLength ();
1541 // update data buffer to package data
1543 ObjBinBuf
= gCFormPkg
.IfrBinBufferGet (mObjBinLen
);
1544 if (ObjBinBuf
!= NULL
) {
1545 memmove (ObjBinBuf
, mObjBinBuf
, mObjBinLen
);
1549 // update bin buffer to package data buffer
1551 if (mObjBinBuf
!= NULL
) {
1553 mObjBinBuf
= ObjBinBuf
;
1560 * The definition of CIfrObj's member function
1565 } gOpcodeSizesScopeTable
[] = {
1566 { 0, 0 }, // EFI_IFR_INVALID - 0x00
1567 { sizeof (EFI_IFR_FORM
), 1 }, // EFI_IFR_FORM_OP
1568 { sizeof (EFI_IFR_SUBTITLE
), 1 }, // EFI_IFR_SUBTITLE_OP
1569 { sizeof (EFI_IFR_TEXT
), 0 }, // EFI_IFR_TEXT_OP
1570 { sizeof (EFI_IFR_IMAGE
), 0 }, // EFI_IFR_IMAGE_OP
1571 { sizeof (EFI_IFR_ONE_OF
), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
1572 { sizeof (EFI_IFR_CHECKBOX
), 1}, // EFI_IFR_CHECKBOX_OP
1573 { sizeof (EFI_IFR_NUMERIC
), 1 }, // EFI_IFR_NUMERIC_OP
1574 { sizeof (EFI_IFR_PASSWORD
), 1 }, // EFI_IFR_PASSWORD_OP
1575 { sizeof (EFI_IFR_ONE_OF_OPTION
), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
1576 { sizeof (EFI_IFR_SUPPRESS_IF
), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
1577 { sizeof (EFI_IFR_LOCKED
), 0 }, // EFI_IFR_LOCKED_OP
1578 { sizeof (EFI_IFR_ACTION
), 1 }, // EFI_IFR_ACTION_OP
1579 { sizeof (EFI_IFR_RESET_BUTTON
), 1 }, // EFI_IFR_RESET_BUTTON_OP
1580 { sizeof (EFI_IFR_FORM_SET
), 1 }, // EFI_IFR_FORM_SET_OP -0xE
1581 { sizeof (EFI_IFR_REF
), 0 }, // EFI_IFR_REF_OP
1582 { sizeof (EFI_IFR_NO_SUBMIT_IF
), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
1583 { sizeof (EFI_IFR_INCONSISTENT_IF
), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
1584 { sizeof (EFI_IFR_EQ_ID_VAL
), 0 }, // EFI_IFR_EQ_ID_VAL_OP
1585 { sizeof (EFI_IFR_EQ_ID_ID
), 0 }, // EFI_IFR_EQ_ID_ID_OP
1586 { sizeof (EFI_IFR_EQ_ID_VAL_LIST
), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
1587 { sizeof (EFI_IFR_AND
), 0 }, // EFI_IFR_AND_OP
1588 { sizeof (EFI_IFR_OR
), 0 }, // EFI_IFR_OR_OP
1589 { sizeof (EFI_IFR_NOT
), 0 }, // EFI_IFR_NOT_OP
1590 { sizeof (EFI_IFR_RULE
), 1 }, // EFI_IFR_RULE_OP
1591 { sizeof (EFI_IFR_GRAY_OUT_IF
), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
1592 { sizeof (EFI_IFR_DATE
), 1 }, // EFI_IFR_DATE_OP
1593 { sizeof (EFI_IFR_TIME
), 1 }, // EFI_IFR_TIME_OP
1594 { sizeof (EFI_IFR_STRING
), 1 }, // EFI_IFR_STRING_OP
1595 { sizeof (EFI_IFR_REFRESH
), 0 }, // EFI_IFR_REFRESH_OP
1596 { sizeof (EFI_IFR_DISABLE_IF
), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
1598 { sizeof (EFI_IFR_TO_LOWER
), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
1599 { sizeof (EFI_IFR_TO_UPPER
), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
1600 { sizeof (EFI_IFR_MAP
), 1 }, // EFI_IFR_MAP - 0x22
1601 { sizeof (EFI_IFR_ORDERED_LIST
), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
1602 { sizeof (EFI_IFR_VARSTORE
), 0 }, // EFI_IFR_VARSTORE_OP
1603 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE
), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
1604 { sizeof (EFI_IFR_VARSTORE_EFI
), 0 }, // EFI_IFR_VARSTORE_EFI_OP
1605 { sizeof (EFI_IFR_VARSTORE_DEVICE
), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
1606 { sizeof (EFI_IFR_VERSION
), 0 }, // EFI_IFR_VERSION_OP - 0x28
1607 { sizeof (EFI_IFR_END
), 0 }, // EFI_IFR_END_OP
1608 { sizeof (EFI_IFR_MATCH
), 0 }, // EFI_IFR_MATCH_OP - 0x2A
1609 { sizeof (EFI_IFR_GET
), 0 }, // EFI_IFR_GET - 0x2B
1610 { sizeof (EFI_IFR_SET
), 0 }, // EFI_IFR_SET - 0x2C
1611 { sizeof (EFI_IFR_READ
), 0 }, // EFI_IFR_READ - 0x2D
1612 { sizeof (EFI_IFR_WRITE
), 0 }, // EFI_IFR_WRITE - 0x2E
1613 { sizeof (EFI_IFR_EQUAL
), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
1614 { sizeof (EFI_IFR_NOT_EQUAL
), 0 }, // EFI_IFR_NOT_EQUAL_OP
1615 { sizeof (EFI_IFR_GREATER_THAN
), 0 }, // EFI_IFR_GREATER_THAN_OP
1616 { sizeof (EFI_IFR_GREATER_EQUAL
), 0 }, // EFI_IFR_GREATER_EQUAL_OP
1617 { sizeof (EFI_IFR_LESS_THAN
), 0 }, // EFI_IFR_LESS_THAN_OP
1618 { sizeof (EFI_IFR_LESS_EQUAL
), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
1619 { sizeof (EFI_IFR_BITWISE_AND
), 0 }, // EFI_IFR_BITWISE_AND_OP
1620 { sizeof (EFI_IFR_BITWISE_OR
), 0 }, // EFI_IFR_BITWISE_OR_OP
1621 { sizeof (EFI_IFR_BITWISE_NOT
), 0 }, // EFI_IFR_BITWISE_NOT_OP
1622 { sizeof (EFI_IFR_SHIFT_LEFT
), 0 }, // EFI_IFR_SHIFT_LEFT_OP
1623 { sizeof (EFI_IFR_SHIFT_RIGHT
), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
1624 { sizeof (EFI_IFR_ADD
), 0 }, // EFI_IFR_ADD_OP - 0x3A
1625 { sizeof (EFI_IFR_SUBTRACT
), 0 }, // EFI_IFR_SUBTRACT_OP
1626 { sizeof (EFI_IFR_MULTIPLY
), 0 }, // EFI_IFR_MULTIPLY_OP
1627 { sizeof (EFI_IFR_DIVIDE
), 0 }, // EFI_IFR_DIVIDE_OP
1628 { sizeof (EFI_IFR_MODULO
), 0 }, // EFI_IFR_MODULO_OP - 0x3E
1629 { sizeof (EFI_IFR_RULE_REF
), 0 }, // EFI_IFR_RULE_REF_OP
1630 { sizeof (EFI_IFR_QUESTION_REF1
), 0 }, // EFI_IFR_QUESTION_REF1_OP
1631 { sizeof (EFI_IFR_QUESTION_REF2
), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
1632 { sizeof (EFI_IFR_UINT8
), 0}, // EFI_IFR_UINT8
1633 { sizeof (EFI_IFR_UINT16
), 0}, // EFI_IFR_UINT16
1634 { sizeof (EFI_IFR_UINT32
), 0}, // EFI_IFR_UINT32
1635 { sizeof (EFI_IFR_UINT64
), 0}, // EFI_IFR_UTNT64
1636 { sizeof (EFI_IFR_TRUE
), 0 }, // EFI_IFR_TRUE_OP - 0x46
1637 { sizeof (EFI_IFR_FALSE
), 0 }, // EFI_IFR_FALSE_OP
1638 { sizeof (EFI_IFR_TO_UINT
), 0 }, // EFI_IFR_TO_UINT_OP
1639 { sizeof (EFI_IFR_TO_STRING
), 0 }, // EFI_IFR_TO_STRING_OP
1640 { sizeof (EFI_IFR_TO_BOOLEAN
), 0 }, // EFI_IFR_TO_BOOLEAN_OP
1641 { sizeof (EFI_IFR_MID
), 0 }, // EFI_IFR_MID_OP
1642 { sizeof (EFI_IFR_FIND
), 0 }, // EFI_IFR_FIND_OP
1643 { sizeof (EFI_IFR_TOKEN
), 0 }, // EFI_IFR_TOKEN_OP
1644 { sizeof (EFI_IFR_STRING_REF1
), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
1645 { sizeof (EFI_IFR_STRING_REF2
), 0 }, // EFI_IFR_STRING_REF2_OP
1646 { sizeof (EFI_IFR_CONDITIONAL
), 0 }, // EFI_IFR_CONDITIONAL_OP
1647 { sizeof (EFI_IFR_QUESTION_REF3
), 0 }, // EFI_IFR_QUESTION_REF3_OP
1648 { sizeof (EFI_IFR_ZERO
), 0 }, // EFI_IFR_ZERO_OP
1649 { sizeof (EFI_IFR_ONE
), 0 }, // EFI_IFR_ONE_OP
1650 { sizeof (EFI_IFR_ONES
), 0 }, // EFI_IFR_ONES_OP
1651 { sizeof (EFI_IFR_UNDEFINED
), 0 }, // EFI_IFR_UNDEFINED_OP
1652 { sizeof (EFI_IFR_LENGTH
), 0 }, // EFI_IFR_LENGTH_OP
1653 { sizeof (EFI_IFR_DUP
), 0 }, // EFI_IFR_DUP_OP - 0x57
1654 { sizeof (EFI_IFR_THIS
), 0 }, // EFI_IFR_THIS_OP
1655 { sizeof (EFI_IFR_SPAN
), 0 }, // EFI_IFR_SPAN_OP
1656 { sizeof (EFI_IFR_VALUE
), 1 }, // EFI_IFR_VALUE_OP
1657 { sizeof (EFI_IFR_DEFAULT
), 0 }, // EFI_IFR_DEFAULT_OP
1658 { sizeof (EFI_IFR_DEFAULTSTORE
), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
1659 { sizeof (EFI_IFR_FORM_MAP
), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
1660 { sizeof (EFI_IFR_CATENATE
), 0 }, // EFI_IFR_CATENATE_OP
1661 { sizeof (EFI_IFR_GUID
), 0 }, // EFI_IFR_GUID_OP
1662 { sizeof (EFI_IFR_SECURITY
), 0 }, // EFI_IFR_SECURITY_OP - 0x60
1663 { sizeof (EFI_IFR_MODAL_TAG
), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
1664 { sizeof (EFI_IFR_REFRESH_ID
), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
1665 { sizeof (EFI_IFR_WARNING_IF
), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
1666 { sizeof (EFI_IFR_MATCH2
), 0 }, // EFI_IFR_MATCH2_OP - 0x64
1669 #ifdef CIFROBJ_DEUBG
1672 } gIfrObjPrintDebugTable
[] = {
1673 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
1674 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
1675 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
1676 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
1677 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
1678 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
1679 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
1680 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
1681 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
1682 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
1683 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
1684 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
1685 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
1686 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
1687 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
1688 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
1689 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
1693 CIFROBJ_DEBUG_PRINT (
1697 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable
[OpCode
].mIfrName
);
1701 #define CIFROBJ_DEBUG_PRINT(OpCode)
1705 BOOLEAN gCreateOp
= TRUE
;
1711 IN BOOLEAN DelayEmit
1714 mDelayEmit
= DelayEmit
;
1715 mPkgOffset
= gCFormPkg
.GetPkgLength ();
1716 mObjBinLen
= (ObjBinLen
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: ObjBinLen
;
1717 mObjBinBuf
= ((DelayEmit
== FALSE
) && (gCreateOp
== TRUE
)) ? gCFormPkg
.IfrBinBufferGet (mObjBinLen
) : new CHAR8
[EFI_IFR_MAX_LENGTH
];
1718 mRecordIdx
= (gCreateOp
== TRUE
) ? gCIfrRecordInfoDB
.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf
, mObjBinLen
, mPkgOffset
) : EFI_IFR_RECORDINFO_IDX_INVALUD
;
1720 if (IfrObj
!= NULL
) {
1721 *IfrObj
= mObjBinBuf
;
1724 CIFROBJ_DEBUG_PRINT (OpCode
);
1731 if ((mDelayEmit
== TRUE
) && ((gCreateOp
== TRUE
))) {
1732 _EMIT_PENDING_OBJ ();
1735 gCIfrRecordInfoDB
.IfrRecordInfoUpdate (mRecordIdx
, mLineNo
, mObjBinBuf
, mObjBinLen
, mPkgOffset
);
1739 * The definition of CIfrObj's member function
1741 UINT8 gScopeCount
= 0;
1743 CIfrOpHeader::CIfrOpHeader (
1747 ) : mHeader ((EFI_IFR_OP_HEADER
*)StartAddr
)
1749 mHeader
->OpCode
= OpCode
;
1750 mHeader
->Length
= (Length
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: Length
;
1751 mHeader
->Scope
= (gOpcodeSizesScopeTable
[OpCode
].mScope
+ gScopeCount
> 0) ? 1 : 0;
1754 CIfrOpHeader::CIfrOpHeader (
1755 IN CIfrOpHeader
&OpHdr
1758 mHeader
= OpHdr
.mHeader
;
1761 UINT32
CIfrFormId::FormIdBitMap
[EFI_FREE_FORM_ID_BITMAP_SIZE
] = {0, };