3 The definition of CFormPkg's member function
5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "VfrFormPkg.h"
20 * The definition of CFormPkg's member function
23 SPendingAssign::SPendingAssign (
39 mKey
= new CHAR8
[strlen (Key
) + 1];
46 mMsg
= new CHAR8
[strlen (Msg
) + 1];
53 SPendingAssign::~SPendingAssign (
70 SPendingAssign::SetAddrAndLen (
80 SPendingAssign::AssignValue (
85 memmove (mAddr
, Addr
, (mLen
< Len
? mLen
: Len
));
90 SPendingAssign::GetKey (
106 mBufferNodeQueueHead
= NULL
;
107 mCurrBufferNode
= NULL
;
109 Node
= new SBufferNode
;
113 BufferStart
= new CHAR8
[BufferSize
];
114 if (BufferStart
== NULL
) {
117 BufferEnd
= BufferStart
+ BufferSize
;
119 memset (BufferStart
, 0, BufferSize
);
120 Node
->mBufferStart
= BufferStart
;
121 Node
->mBufferEnd
= BufferEnd
;
122 Node
->mBufferFree
= BufferStart
;
125 mBufferSize
= BufferSize
;
126 mBufferNodeQueueHead
= Node
;
127 mBufferNodeQueueTail
= Node
;
128 mCurrBufferNode
= Node
;
131 CFormPkg::~CFormPkg ()
134 SPendingAssign
*pPNode
;
136 while (mBufferNodeQueueHead
!= NULL
) {
137 pBNode
= mBufferNodeQueueHead
;
138 mBufferNodeQueueHead
= mBufferNodeQueueHead
->mNext
;
139 if (pBNode
->mBufferStart
!= NULL
) {
140 delete pBNode
->mBufferStart
;
144 mBufferNodeQueueTail
= NULL
;
145 mCurrBufferNode
= NULL
;
147 while (PendingAssignList
!= NULL
) {
148 pPNode
= PendingAssignList
;
149 PendingAssignList
= PendingAssignList
->mNext
;
152 PendingAssignList
= NULL
;
156 CFormPkg::CreateNewNode (
162 Node
= new SBufferNode
;
167 Node
->mBufferStart
= new CHAR8
[mBufferSize
];
168 if (Node
->mBufferStart
== NULL
) {
172 memset (Node
->mBufferStart
, 0, mBufferSize
);
173 Node
->mBufferEnd
= Node
->mBufferStart
+ mBufferSize
;
174 Node
->mBufferFree
= Node
->mBufferStart
;
182 CFormPkg::IfrBinBufferGet (
186 CHAR8
*BinBuffer
= NULL
;
187 SBufferNode
*Node
= NULL
;
189 if ((Len
== 0) || (Len
> mBufferSize
)) {
193 if ((mCurrBufferNode
->mBufferFree
+ Len
) <= mCurrBufferNode
->mBufferEnd
) {
194 BinBuffer
= mCurrBufferNode
->mBufferFree
;
195 mCurrBufferNode
->mBufferFree
+= Len
;
197 Node
= CreateNewNode ();
202 if (mBufferNodeQueueTail
== NULL
) {
203 mBufferNodeQueueHead
= mBufferNodeQueueTail
= Node
;
205 mBufferNodeQueueTail
->mNext
= Node
;
206 mBufferNodeQueueTail
= Node
;
208 mCurrBufferNode
= Node
;
213 BinBuffer
= mCurrBufferNode
->mBufferFree
;
214 mCurrBufferNode
->mBufferFree
+= Len
;
224 CFormPkg::GetPkgLength (
236 mReadBufferNode
= mBufferNodeQueueHead
;
237 mReadBufferOffset
= 0;
245 mReadBufferNode
= NULL
;
246 mReadBufferOffset
= 0;
257 if ((Size
== 0) || (Buffer
== NULL
)) {
261 if (mReadBufferNode
== NULL
) {
265 for (Index
= 0; Index
< Size
; Index
++) {
266 if ((mReadBufferNode
->mBufferStart
+ mReadBufferOffset
) < mReadBufferNode
->mBufferFree
) {
267 Buffer
[Index
] = mReadBufferNode
->mBufferStart
[mReadBufferOffset
++];
269 if ((mReadBufferNode
= mReadBufferNode
->mNext
) == NULL
) {
272 mReadBufferOffset
= 0;
282 CFormPkg::BuildPkgHdr (
283 OUT EFI_HII_PACKAGE_HEADER
**PkgHdr
286 if (PkgHdr
== NULL
) {
287 return VFR_RETURN_FATAL_ERROR
;
290 if (((*PkgHdr
) = new EFI_HII_PACKAGE_HEADER
) == NULL
) {
291 return VFR_RETURN_OUT_FOR_RESOURCES
;
294 (*PkgHdr
)->Type
= EFI_HII_PACKAGE_FORM
;
295 (*PkgHdr
)->Length
= mPkgLength
+ sizeof (EFI_HII_PACKAGE_HEADER
);
297 return VFR_RETURN_SUCCESS
;
302 OUT PACKAGE_DATA
&TBuffer
310 if (TBuffer
.Buffer
!= NULL
) {
311 delete TBuffer
.Buffer
;
314 TBuffer
.Size
= mPkgLength
;
315 TBuffer
.Buffer
= NULL
;
316 if (TBuffer
.Size
!= 0) {
317 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
319 return VFR_RETURN_SUCCESS
;
322 Temp
= TBuffer
.Buffer
;
324 while ((Size
= Read (Buffer
, 1024)) != 0) {
325 memcpy (Temp
, Buffer
, Size
);
329 return VFR_RETURN_SUCCESS
;
336 IN PACKAGE_DATA
*PkgData
339 EFI_VFR_RETURN_CODE Ret
;
342 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
344 if (Output
== NULL
) {
345 return VFR_RETURN_FATAL_ERROR
;
348 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
351 fwrite (PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
), 1, Output
);
354 if (PkgData
== NULL
) {
356 while ((Size
= Read (Buffer
, 1024)) != 0) {
357 fwrite (Buffer
, Size
, 1, Output
);
361 fwrite (PkgData
->Buffer
, PkgData
->Size
, 1, Output
);
364 return VFR_RETURN_SUCCESS
;
368 CFormPkg::_WRITE_PKG_LINE (
371 IN CONST CHAR8
*LineHeader
,
378 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
382 for (Index
= 0; Index
< BlkSize
; Index
++) {
383 if ((Index
% LineBytes
) == 0) {
384 fprintf (pFile
, "\n%s", LineHeader
);
386 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
391 CFormPkg::_WRITE_PKG_END (
394 IN CONST CHAR8
*LineHeader
,
401 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
405 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
406 if ((Index
% LineBytes
) == 0) {
407 fprintf (pFile
, "\n%s", LineHeader
);
409 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
412 if ((Index
% LineBytes
) == 0) {
413 fprintf (pFile
, "\n%s", LineHeader
);
415 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
418 #define BYTES_PRE_LINE 0x10
419 UINT32 gAdjustOpcodeOffset
= 0;
420 BOOLEAN gNeedAdjustOpcode
= FALSE
;
421 UINT32 gAdjustOpcodeLen
= 0;
427 IN PACKAGE_DATA
*PkgData
430 EFI_VFR_RETURN_CODE Ret
;
431 CHAR8 Buffer
[BYTES_PRE_LINE
* 8];
432 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
433 UINT32 PkgLength
= 0;
436 if ((BaseName
== NULL
) || (pFile
== NULL
)) {
437 return VFR_RETURN_FATAL_ERROR
;
440 fprintf (pFile
, "\nunsigned char %sBin[] = {\n", BaseName
);
442 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
447 // For framework vfr file, the extension framework header will be added.
449 if (VfrCompatibleMode
) {
450 fprintf (pFile
, " // FRAMEWORK PACKAGE HEADER Length\n");
451 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
) + 2;
452 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
453 fprintf (pFile
, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
455 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT16
));
457 fprintf (pFile
, " // ARRAY LENGTH\n");
458 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
);
459 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
462 fprintf (pFile
, "\n\n // PACKAGE HEADER\n");
463 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
464 PkgLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
466 fprintf (pFile
, "\n\n // PACKAGE DATA\n");
468 if (PkgData
== NULL
) {
470 while ((ReadSize
= Read ((CHAR8
*)Buffer
, BYTES_PRE_LINE
* 8)) != 0) {
471 PkgLength
+= ReadSize
;
472 if (PkgLength
< PkgHdr
->Length
) {
473 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
475 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
480 if (PkgData
->Size
% BYTES_PRE_LINE
!= 0) {
481 PkgLength
= PkgData
->Size
- (PkgData
->Size
% BYTES_PRE_LINE
);
482 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
483 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, PkgData
->Size
% BYTES_PRE_LINE
);
485 PkgLength
= PkgData
->Size
- BYTES_PRE_LINE
;
486 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
487 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, BYTES_PRE_LINE
);
492 fprintf (pFile
, "\n};\n");
494 return VFR_RETURN_SUCCESS
;
498 CFormPkg::AssignPending (
506 SPendingAssign
*pNew
;
508 pNew
= new SPendingAssign (Key
, ValAddr
, ValLen
, LineNo
, Msg
);
510 return VFR_RETURN_OUT_FOR_RESOURCES
;
513 pNew
->mNext
= PendingAssignList
;
514 PendingAssignList
= pNew
;
515 return VFR_RETURN_SUCCESS
;
519 CFormPkg::DoPendingAssign (
525 SPendingAssign
*pNode
;
527 if ((Key
== NULL
) || (ValAddr
== NULL
)) {
531 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
532 if (strcmp (pNode
->mKey
, Key
) == 0) {
533 pNode
->AssignValue (ValAddr
, ValLen
);
539 CFormPkg::HavePendingUnassigned (
543 SPendingAssign
*pNode
;
545 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
546 if (pNode
->mFlag
== PENDING
) {
555 CFormPkg::PendingAssignPrintAll (
559 SPendingAssign
*pNode
;
561 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
562 if (pNode
->mFlag
== PENDING
) {
563 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", pNode
->mMsg
);
569 CFormPkg::GetBinBufferNodeForAddr (
570 IN CHAR8
*BinBuffAddr
573 SBufferNode
*TmpNode
;
575 TmpNode
= mBufferNodeQueueHead
;
577 while (TmpNode
!= NULL
) {
578 if (TmpNode
->mBufferStart
<= BinBuffAddr
&& TmpNode
->mBufferFree
>= BinBuffAddr
) {
582 TmpNode
= TmpNode
->mNext
;
589 CFormPkg::GetNodeBefore(
590 IN SBufferNode
*CurrentNode
593 SBufferNode
*FirstNode
= mBufferNodeQueueHead
;
594 SBufferNode
*LastNode
= mBufferNodeQueueHead
;
596 while (FirstNode
!= NULL
) {
597 if (FirstNode
== CurrentNode
) {
601 LastNode
= FirstNode
;
602 FirstNode
= FirstNode
->mNext
;
605 if (FirstNode
== NULL
) {
613 CFormPkg::InsertNodeBefore(
614 IN SBufferNode
*CurrentNode
,
615 IN SBufferNode
*NewNode
618 SBufferNode
*LastNode
= GetNodeBefore (CurrentNode
);
620 if (LastNode
== NULL
) {
621 return VFR_RETURN_MISMATCHED
;
624 NewNode
->mNext
= LastNode
->mNext
;
625 LastNode
->mNext
= NewNode
;
627 return VFR_RETURN_SUCCESS
;
631 CFormPkg::GetBufAddrBaseOnOffset (
635 SBufferNode
*TmpNode
;
637 UINT32 CurrentBufLen
;
641 for (TmpNode
= mBufferNodeQueueHead
; TmpNode
!= NULL
; TmpNode
= TmpNode
->mNext
) {
642 CurrentBufLen
= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
643 if (Offset
>= TotalBufLen
&& Offset
< TotalBufLen
+ CurrentBufLen
) {
644 return TmpNode
->mBufferStart
+ (Offset
- TotalBufLen
);
647 TotalBufLen
+= CurrentBufLen
;
654 CFormPkg::AdjustDynamicInsertOpcode (
655 IN CHAR8
*InserPositionAddr
,
656 IN CHAR8
*InsertOpcodeAddr
,
657 IN BOOLEAN CreateOpcodeAfterParsingVfr
660 SBufferNode
*InserPositionNode
;
661 SBufferNode
*InsertOpcodeNode
;
662 SBufferNode
*NewRestoreNodeBegin
;
663 SBufferNode
*NewRestoreNodeEnd
;
664 SBufferNode
*NewLastEndNode
;
665 SBufferNode
*TmpNode
;
666 UINT32 NeedRestoreCodeLen
;
668 NewRestoreNodeEnd
= NULL
;
670 InserPositionNode
= GetBinBufferNodeForAddr(InserPositionAddr
);
671 InsertOpcodeNode
= GetBinBufferNodeForAddr(InsertOpcodeAddr
);
673 if (InserPositionNode
== InsertOpcodeNode
) {
675 // Create New Node to save the restore opcode.
677 NeedRestoreCodeLen
= InsertOpcodeAddr
- InserPositionAddr
;
678 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
679 NewRestoreNodeBegin
= CreateNewNode ();
680 if (NewRestoreNodeBegin
== NULL
) {
681 return VFR_RETURN_OUT_FOR_RESOURCES
;
683 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
684 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
687 // Override the restore buffer data.
689 memmove (InserPositionAddr
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
690 InsertOpcodeNode
->mBufferFree
-= NeedRestoreCodeLen
;
691 memset (InsertOpcodeNode
->mBufferFree
, 0, NeedRestoreCodeLen
);
694 // Create New Node to save the restore opcode.
696 NeedRestoreCodeLen
= InserPositionNode
->mBufferFree
- InserPositionAddr
;
697 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
698 NewRestoreNodeBegin
= CreateNewNode ();
699 if (NewRestoreNodeBegin
== NULL
) {
700 return VFR_RETURN_OUT_FOR_RESOURCES
;
702 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
703 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
705 // Override the restore buffer data.
707 InserPositionNode
->mBufferFree
-= NeedRestoreCodeLen
;
709 // Link the restore data to new node.
711 NewRestoreNodeBegin
->mNext
= InserPositionNode
->mNext
;
714 // Count the Adjust opcode len.
716 TmpNode
= InserPositionNode
->mNext
;
717 while (TmpNode
!= InsertOpcodeNode
) {
718 gAdjustOpcodeLen
+= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
719 TmpNode
= TmpNode
->mNext
;
723 // Create New Node to save the last node of restore opcode.
725 NeedRestoreCodeLen
= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
726 gAdjustOpcodeLen
+= NeedRestoreCodeLen
;
727 if (NeedRestoreCodeLen
> 0) {
728 NewRestoreNodeEnd
= CreateNewNode ();
729 if (NewRestoreNodeEnd
== NULL
) {
730 return VFR_RETURN_OUT_FOR_RESOURCES
;
732 memcpy (NewRestoreNodeEnd
->mBufferFree
, InsertOpcodeNode
->mBufferStart
, NeedRestoreCodeLen
);
733 NewRestoreNodeEnd
->mBufferFree
+= NeedRestoreCodeLen
;
735 // Override the restore buffer data.
737 memmove (InsertOpcodeNode
->mBufferStart
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
738 InsertOpcodeNode
->mBufferFree
-= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
741 // Insert the last restore data node.
743 TmpNode
= GetNodeBefore (InsertOpcodeNode
);
744 if (TmpNode
== InserPositionNode
) {
745 NewRestoreNodeBegin
->mNext
= NewRestoreNodeEnd
;
747 TmpNode
->mNext
= NewRestoreNodeEnd
;
750 // Connect the dynamic opcode node to the node after InserPositionNode.
752 InserPositionNode
->mNext
= InsertOpcodeNode
;
756 if (CreateOpcodeAfterParsingVfr
) {
758 // Th new opcodes were created after Parsing Vfr file,
759 // so the content in mBufferNodeQueueTail must be the new created opcodes.
760 // So connet the NewRestoreNodeBegin to the tail and update the tail node.
762 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
763 if (NewRestoreNodeEnd
!= NULL
) {
764 mBufferNodeQueueTail
= NewRestoreNodeEnd
;
766 mBufferNodeQueueTail
= NewRestoreNodeBegin
;
769 if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
> 2) {
771 // End form set opcode all in the mBufferNodeQueueTail node.
773 NewLastEndNode
= CreateNewNode ();
774 if (NewLastEndNode
== NULL
) {
775 return VFR_RETURN_OUT_FOR_RESOURCES
;
777 NewLastEndNode
->mBufferStart
[0] = 0x29;
778 NewLastEndNode
->mBufferStart
[1] = 0x02;
779 NewLastEndNode
->mBufferFree
+= 2;
781 mBufferNodeQueueTail
->mBufferFree
-= 2;
783 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
784 if (NewRestoreNodeEnd
!= NULL
) {
785 NewRestoreNodeEnd
->mNext
= NewLastEndNode
;
787 NewRestoreNodeBegin
->mNext
= NewLastEndNode
;
790 mBufferNodeQueueTail
= NewLastEndNode
;
791 } else if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
== 2) {
792 TmpNode
= GetNodeBefore(mBufferNodeQueueTail
);
793 TmpNode
->mNext
= NewRestoreNodeBegin
;
794 if (NewRestoreNodeEnd
!= NULL
) {
795 NewRestoreNodeEnd
->mNext
= mBufferNodeQueueTail
;
797 NewRestoreNodeBegin
->mNext
= mBufferNodeQueueTail
;
801 mCurrBufferNode
= mBufferNodeQueueTail
;
802 return VFR_RETURN_SUCCESS
;
806 CFormPkg::DeclarePendingQuestion (
807 IN CVfrVarDataTypeDB
&lCVfrVarDataTypeDB
,
808 IN CVfrDataStorage
&lCVfrDataStorage
,
809 IN CVfrQuestionDB
&lCVfrQuestionDB
,
810 IN EFI_GUID
*LocalFormSetGuid
,
812 OUT CHAR8
**InsertOpcodeAddr
815 SPendingAssign
*pNode
;
818 CHAR8 FName
[MAX_NAME_LEN
];
822 EFI_VFR_RETURN_CODE ReturnCode
;
823 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
824 EFI_VARSTORE_ID VarStoreId
= EFI_VARSTORE_ID_INVALID
;
827 // Declare all questions as Numeric in DisableIf True
831 DIObj
.SetLineNo (LineNo
);
832 *InsertOpcodeAddr
= DIObj
.GetObjBinAddr ();
835 CIfrTrue
TObj (LineNo
);
837 // Declare Numeric qeustion for each undefined question.
838 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
839 if (pNode
->mFlag
== PENDING
) {
841 EFI_VARSTORE_INFO Info
;
842 EFI_QUESTION_ID QId
= EFI_QUESTION_ID_INVALID
;
844 CNObj
.SetLineNo (LineNo
);
845 CNObj
.SetPrompt (0x0);
849 // Register this question, assume it is normal question, not date or time question
851 VarStr
= pNode
->mKey
;
852 ReturnCode
= lCVfrQuestionDB
.RegisterQuestion (NULL
, VarStr
, QId
);
853 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
854 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
859 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr
, QId
);
862 // Get Question Info, framework vfr VarName == StructName
864 ReturnCode
= lCVfrVarDataTypeDB
.ExtractFieldNameAndArrary (VarStr
, FName
, ArrayIdx
);
865 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
866 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", "Var string is not the valid C variable");
872 ReturnCode
= lCVfrDataStorage
.GetVarStoreId (FName
, &Info
.mVarStoreId
);
873 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
874 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, FName
, "Error", "Var Store Type is not defined");
877 VarStoreType
= lCVfrDataStorage
.GetVarStoreType (Info
.mVarStoreId
);
879 if (*VarStr
== '\0' && ArrayIdx
!= INVALID_ARRAY_INDEX
) {
880 ReturnCode
= lCVfrDataStorage
.GetNameVarStoreInfo (&Info
, ArrayIdx
);
882 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
883 ReturnCode
= lCVfrDataStorage
.GetEfiVarStoreInfo (&Info
);
884 } else if (VarStoreType
== EFI_VFR_VARSTORE_BUFFER
) {
885 VarStr
= pNode
->mKey
;
886 //convert VarStr with store name to VarStr with structure name
887 ReturnCode
= lCVfrDataStorage
.GetBufferVarStoreDataTypeName (Info
.mVarStoreId
, &SName
);
888 if (ReturnCode
== VFR_RETURN_SUCCESS
) {
889 NewStr
= new CHAR8
[strlen (VarStr
) + strlen (SName
) + 1];
891 strcpy (NewStr
, SName
);
892 strcat (NewStr
, VarStr
+ strlen (FName
));
893 ReturnCode
= lCVfrVarDataTypeDB
.GetDataFieldInfo (NewStr
, Info
.mInfo
.mVarOffset
, Info
.mVarType
, Info
.mVarTotalSize
);
897 ReturnCode
= VFR_RETURN_UNSUPPORTED
;
900 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
901 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
905 CNObj
.SetQuestionId (QId
);
906 CNObj
.SetVarStoreInfo (&Info
);
908 // Numeric doesn't support BOOLEAN data type.
909 // BOOLEAN type has the same data size to UINT8.
911 if (Info
.mVarType
== EFI_IFR_TYPE_BOOLEAN
) {
912 Info
.mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
914 CNObj
.SetFlags (0, Info
.mVarType
);
916 // Use maximum value not to limit the vaild value for the undefined question.
918 switch (Info
.mVarType
) {
919 case EFI_IFR_TYPE_NUM_SIZE_64
:
920 CNObj
.SetMinMaxStepData ((UINT64
) 0, (UINT64
) -1 , (UINT64
) 0);
923 case EFI_IFR_TYPE_NUM_SIZE_32
:
924 CNObj
.SetMinMaxStepData ((UINT32
) 0, (UINT32
) -1 , (UINT32
) 0);
927 case EFI_IFR_TYPE_NUM_SIZE_16
:
928 CNObj
.SetMinMaxStepData ((UINT16
) 0, (UINT16
) -1 , (UINT16
) 0);
931 case EFI_IFR_TYPE_NUM_SIZE_8
:
932 CNObj
.SetMinMaxStepData ((UINT8
) 0, (UINT8
) -1 , (UINT8
) 0);
938 CNObj
.ShrinkBinSize (ShrinkSize
);
941 // For undefined Efi VarStore type question
942 // Append the extended guided opcode to contain VarName
944 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
|| VfrCompatibleMode
) {
945 CIfrVarEqName
CVNObj (QId
, Info
.mInfo
.mVarName
);
946 CVNObj
.SetLineNo (LineNo
);
953 CEObj
.SetLineNo (LineNo
);
961 SEObj
.SetLineNo (LineNo
);
963 return VFR_RETURN_SUCCESS
;
968 SIfrRecord::SIfrRecord (
974 mLineNo
= 0xFFFFFFFF;
975 mOffset
= 0xFFFFFFFF;
979 SIfrRecord::~SIfrRecord (
983 if (mIfrBinBuf
!= NULL
) {
987 mLineNo
= 0xFFFFFFFF;
988 mOffset
= 0xFFFFFFFF;
993 CIfrRecordInfoDB::CIfrRecordInfoDB (
998 mRecordCount
= EFI_IFR_RECORDINFO_IDX_START
;
999 mIfrRecordListHead
= NULL
;
1000 mIfrRecordListTail
= NULL
;
1001 mAllDefaultTypeCount
= 0;
1002 for (UINT8 i
= 0; i
< EFI_HII_MAX_SUPPORT_DEFAULT_TYPE
; i
++) {
1003 mAllDefaultIdArray
[i
] = 0xffff;
1007 CIfrRecordInfoDB::~CIfrRecordInfoDB (
1013 while (mIfrRecordListHead
!= NULL
) {
1014 pNode
= mIfrRecordListHead
;
1015 mIfrRecordListHead
= mIfrRecordListHead
->mNext
;
1021 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1026 SIfrRecord
*pNode
= NULL
;
1028 if (RecordIdx
== EFI_IFR_RECORDINFO_IDX_INVALUD
) {
1032 for (Idx
= (EFI_IFR_RECORDINFO_IDX_START
+ 1), pNode
= mIfrRecordListHead
;
1033 (Idx
!= RecordIdx
) && (pNode
!= NULL
);
1034 Idx
++, pNode
= pNode
->mNext
)
1041 CIfrRecordInfoDB::IfrRecordRegister (
1043 IN CHAR8
*IfrBinBuf
,
1050 if (mSwitch
== FALSE
) {
1051 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1054 if ((pNew
= new SIfrRecord
) == NULL
) {
1055 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1058 if (mIfrRecordListHead
== NULL
) {
1059 mIfrRecordListHead
= pNew
;
1060 mIfrRecordListTail
= pNew
;
1062 mIfrRecordListTail
->mNext
= pNew
;
1063 mIfrRecordListTail
= pNew
;
1067 return mRecordCount
;
1071 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1072 IN UINT32 RecordIdx
,
1082 if ((pNode
= GetRecordInfoFromIdx (RecordIdx
)) == NULL
) {
1088 // Line number is not specified explicitly, try to use line number of previous opcode
1090 Prev
= GetRecordInfoFromIdx (RecordIdx
- 1);
1092 LineNo
= Prev
->mLineNo
;
1096 pNode
->mLineNo
= LineNo
;
1097 pNode
->mOffset
= Offset
;
1098 pNode
->mBinBufLen
= BinBufLen
;
1099 pNode
->mIfrBinBuf
= BinBuf
;
1104 CIfrRecordInfoDB::IfrRecordOutput (
1105 OUT PACKAGE_DATA
&TBuffer
1111 if (TBuffer
.Buffer
!= NULL
) {
1112 delete TBuffer
.Buffer
;
1116 TBuffer
.Buffer
= NULL
;
1119 if (mSwitch
== FALSE
) {
1123 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1124 TBuffer
.Size
+= pNode
->mBinBufLen
;
1127 if (TBuffer
.Size
!= 0) {
1128 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
1133 Temp
= TBuffer
.Buffer
;
1135 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1136 if (pNode
->mIfrBinBuf
!= NULL
) {
1137 memcpy (Temp
, pNode
->mIfrBinBuf
, pNode
->mBinBufLen
);
1138 Temp
+= pNode
->mBinBufLen
;
1146 CIfrRecordInfoDB::IfrRecordOutput (
1155 if (mSwitch
== FALSE
) {
1165 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1166 if (pNode
->mLineNo
== LineNo
|| LineNo
== 0) {
1167 fprintf (File
, ">%08X: ", pNode
->mOffset
);
1168 TotalSize
+= pNode
->mBinBufLen
;
1169 if (pNode
->mIfrBinBuf
!= NULL
) {
1170 for (Index
= 0; Index
< pNode
->mBinBufLen
; Index
++) {
1171 fprintf (File
, "%02X ", (UINT8
)(pNode
->mIfrBinBuf
[Index
]));
1174 fprintf (File
, "\n");
1179 fprintf (File
, "\nTotal Size of all record is 0x%08X\n", TotalSize
);
1184 // for framework vfr file
1185 // adjust opcode sequence for uefi IFR format
1186 // adjust inconsistent and varstore into the right position.
1189 CIfrRecordInfoDB::CheckQuestionOpCode (
1194 case EFI_IFR_CHECKBOX_OP
:
1195 case EFI_IFR_NUMERIC_OP
:
1196 case EFI_IFR_PASSWORD_OP
:
1197 case EFI_IFR_ONE_OF_OP
:
1198 case EFI_IFR_ACTION_OP
:
1199 case EFI_IFR_STRING_OP
:
1200 case EFI_IFR_DATE_OP
:
1201 case EFI_IFR_TIME_OP
:
1202 case EFI_IFR_ORDERED_LIST_OP
:
1203 case EFI_IFR_REF_OP
:
1204 case EFI_IFR_RESET_BUTTON_OP
:
1212 CIfrRecordInfoDB::CheckIdOpCode (
1217 case EFI_IFR_EQ_ID_VAL_OP
:
1218 case EFI_IFR_EQ_ID_ID_OP
:
1219 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1220 case EFI_IFR_QUESTION_REF1_OP
:
1228 CIfrRecordInfoDB::GetOpcodeQuestionId (
1229 IN EFI_IFR_OP_HEADER
*OpHead
1232 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1234 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (OpHead
+ 1);
1236 return QuestionHead
->QuestionId
;
1240 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1244 SIfrRecord
*pNode
= NULL
;
1246 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1247 if (pNode
->mOffset
== Offset
) {
1256 Add just the op code position.
1258 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1259 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1263 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1267 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1269 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1270 so new records are appennded to the end of OriginalIfrRecordListTail.
1274 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1278 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1281 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1285 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1286 IN BOOLEAN CreateOpcodeAfterParsingVfr
1289 UINT32 OpcodeOffset
;
1290 SIfrRecord
*pNode
, *pPreNode
;
1291 SIfrRecord
*pAdjustNode
, *pNodeBeforeAdjust
;
1292 SIfrRecord
*pNodeBeforeDynamic
;
1295 pNodeBeforeDynamic
= NULL
;
1299 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1300 // and the node before pDynamicOpcodeNode.
1302 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1303 if (OpcodeOffset
== gAdjustOpcodeOffset
) {
1304 pAdjustNode
= pNode
;
1305 pNodeBeforeAdjust
= pPreNode
;
1306 } else if (OpcodeOffset
== gAdjustOpcodeOffset
+ gAdjustOpcodeLen
) {
1307 pNodeBeforeDynamic
= pPreNode
;
1309 if (pNode
->mNext
!= NULL
) {
1312 OpcodeOffset
+= pNode
->mBinBufLen
;
1316 // Check the nodes whether exist.
1318 if (pNodeBeforeDynamic
== NULL
|| pAdjustNode
== NULL
) {
1323 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1325 pNodeBeforeAdjust
->mNext
= pNodeBeforeDynamic
->mNext
;
1326 if (CreateOpcodeAfterParsingVfr
) {
1328 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1330 mIfrRecordListTail
->mNext
= pAdjustNode
;
1331 mIfrRecordListTail
= pNodeBeforeDynamic
;
1332 mIfrRecordListTail
->mNext
= NULL
;
1335 //pPreNode is the end of pDynamicNode(Case1).
1337 pPreNode
->mNext
= pAdjustNode
;
1338 pNodeBeforeDynamic
->mNext
= mIfrRecordListTail
;
1345 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1347 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1351 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1352 IN BOOLEAN CreateOpcodeAfterParsingVfr
1355 SIfrRecord
*pRecord
;
1358 // Base on the original offset info to update the record list.
1360 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr
)) {
1361 gCVfrErrorHandle
.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");
1365 // Base on the opcode binary length to recalculate the offset for each opcode.
1367 IfrAdjustOffsetForRecord();
1370 // Base on the offset to find the binary address.
1372 pRecord
= GetRecordInfoFromOffset(gAdjustOpcodeOffset
);
1373 while (pRecord
!= NULL
) {
1374 pRecord
->mIfrBinBuf
= gCFormPkg
.GetBufAddrBaseOnOffset(pRecord
->mOffset
);
1375 pRecord
= pRecord
->mNext
;
1381 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1385 UINT32 OpcodeOffset
;
1389 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1390 pNode
->mOffset
= OpcodeOffset
;
1391 OpcodeOffset
+= pNode
->mBinBufLen
;
1396 CIfrRecordInfoDB::IfrRecordAdjust (
1400 SIfrRecord
*pNode
, *preNode
;
1401 SIfrRecord
*uNode
, *tNode
;
1402 EFI_IFR_OP_HEADER
*OpHead
, *tOpHead
;
1403 EFI_QUESTION_ID QuestionId
;
1405 UINT32 QuestionScope
;
1406 UINT32 OpcodeOffset
;
1407 CHAR8 ErrorMsg
[MAX_STRING_LEN
] = {0, };
1408 EFI_VFR_RETURN_CODE Status
;
1411 // Init local variable
1413 Status
= VFR_RETURN_SUCCESS
;
1414 pNode
= mIfrRecordListHead
;
1417 while (pNode
!= NULL
) {
1418 OpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1421 // make sure the inconsistent opcode in question scope
1423 if (QuestionScope
> 0) {
1424 QuestionScope
+= OpHead
->Scope
;
1425 if (OpHead
->OpCode
== EFI_IFR_END_OP
) {
1430 if (CheckQuestionOpCode (OpHead
->OpCode
)) {
1434 // for the inconsistent opcode not in question scope, adjust it
1436 if (OpHead
->OpCode
== EFI_IFR_INCONSISTENT_IF_OP
&& QuestionScope
== 0) {
1438 // for inconsistent opcode not in question scope
1442 // Count inconsistent opcode Scope
1444 StackCount
= OpHead
->Scope
;
1445 QuestionId
= EFI_QUESTION_ID_INVALID
;
1447 while (tNode
!= NULL
&& StackCount
> 0) {
1448 tNode
= tNode
->mNext
;
1449 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mIfrBinBuf
;
1451 // Calculate Scope Number
1453 StackCount
+= tOpHead
->Scope
;
1454 if (tOpHead
->OpCode
== EFI_IFR_END_OP
) {
1458 // by IdEqual opcode to get QuestionId
1460 if (QuestionId
== EFI_QUESTION_ID_INVALID
&&
1461 CheckIdOpCode (tOpHead
->OpCode
)) {
1462 QuestionId
= *(EFI_QUESTION_ID
*) (tOpHead
+ 1);
1465 if (tNode
== NULL
|| QuestionId
== EFI_QUESTION_ID_INVALID
) {
1467 // report error; not found
1469 sprintf (ErrorMsg
, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId
);
1470 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1471 Status
= VFR_RETURN_MISMATCHED
;
1475 // extract inconsistent opcode list
1476 // pNode is Incosistent opcode, tNode is End Opcode
1480 // insert inconsistent opcode list into the right question scope by questionid
1482 for (uNode
= mIfrRecordListHead
; uNode
!= NULL
; uNode
= uNode
->mNext
) {
1483 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mIfrBinBuf
;
1484 if (CheckQuestionOpCode (tOpHead
->OpCode
) &&
1485 (QuestionId
== GetOpcodeQuestionId (tOpHead
))) {
1490 // insert inconsistent opcode list and check LATE_CHECK flag
1492 if (uNode
!= NULL
) {
1493 if ((((EFI_IFR_QUESTION_HEADER
*)(tOpHead
+ 1))->Flags
& 0x20) != 0) {
1495 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1497 OpHead
->OpCode
= EFI_IFR_NO_SUBMIT_IF_OP
;
1501 // skip the default storage for Date and Time
1503 if ((uNode
->mNext
!= NULL
) && (*uNode
->mNext
->mIfrBinBuf
== EFI_IFR_DEFAULT_OP
)) {
1504 uNode
= uNode
->mNext
;
1507 preNode
->mNext
= tNode
->mNext
;
1508 tNode
->mNext
= uNode
->mNext
;
1509 uNode
->mNext
= pNode
;
1511 // reset pNode to head list, scan the whole list again.
1513 pNode
= mIfrRecordListHead
;
1519 // not found matched question id, report error
1521 sprintf (ErrorMsg
, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId
);
1522 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1523 Status
= VFR_RETURN_MISMATCHED
;
1526 } else if (OpHead
->OpCode
== EFI_IFR_VARSTORE_OP
||
1527 OpHead
->OpCode
== EFI_IFR_VARSTORE_EFI_OP
) {
1529 // for new added group of varstore opcode
1532 while (tNode
->mNext
!= NULL
) {
1533 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mNext
->mIfrBinBuf
;
1534 if (tOpHead
->OpCode
!= EFI_IFR_VARSTORE_OP
&&
1535 tOpHead
->OpCode
!= EFI_IFR_VARSTORE_EFI_OP
) {
1538 tNode
= tNode
->mNext
;
1541 if (tNode
->mNext
== NULL
) {
1543 // invalid IfrCode, IfrCode end by EndOpCode
1545 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", "No found End Opcode in the end");
1546 Status
= VFR_RETURN_MISMATCHED
;
1550 if (tOpHead
->OpCode
!= EFI_IFR_END_OP
) {
1552 // not new added varstore, which are not needed to be adjust.
1555 pNode
= tNode
->mNext
;
1559 // move new added varstore opcode to the position befor form opcode
1560 // varstore opcode between pNode and tNode
1564 // search form opcode from begin
1566 for (uNode
= mIfrRecordListHead
; uNode
->mNext
!= NULL
; uNode
= uNode
->mNext
) {
1567 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mNext
->mIfrBinBuf
;
1568 if (tOpHead
->OpCode
== EFI_IFR_FORM_OP
) {
1573 // Insert varstore opcode beform form opcode if form opcode is found
1575 if (uNode
->mNext
!= NULL
) {
1576 preNode
->mNext
= tNode
->mNext
;
1577 tNode
->mNext
= uNode
->mNext
;
1578 uNode
->mNext
= pNode
;
1580 // reset pNode to head list, scan the whole list again.
1582 pNode
= mIfrRecordListHead
;
1588 // not found form, continue scan IfrRecord list
1591 pNode
= tNode
->mNext
;
1600 pNode
= pNode
->mNext
;
1604 // Update Ifr Opcode Offset
1606 if (Status
== VFR_RETURN_SUCCESS
) {
1607 IfrAdjustOffsetForRecord ();
1613 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1614 given by expression, should save the default info for the Buffer VarStore.
1616 @param DefaultId The default id.
1617 @param pQuestionNode Point to the question opcode node.
1618 @param Value The default value.
1621 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1622 IN UINT16 DefaultId
,
1623 IN SIfrRecord
*pQuestionNode
,
1624 IN EFI_IFR_TYPE_VALUE Value
1627 CHAR8
*VarStoreName
= NULL
;
1628 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1629 EFI_GUID
*VarGuid
= NULL
;
1630 EFI_VARSTORE_INFO VarInfo
;
1631 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1632 EFI_IFR_OP_HEADER
*pQuestionOpHead
;
1634 pQuestionOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1635 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (pQuestionOpHead
+ 1);
1638 // Get the Var Store name and type.
1640 gCVfrDataStorage
.GetVarStoreName (QuestionHead
->VarStoreId
, &VarStoreName
);
1641 VarGuid
= gCVfrDataStorage
.GetVarStoreGuid (QuestionHead
->VarStoreId
);
1642 VarStoreType
= gCVfrDataStorage
.GetVarStoreType (QuestionHead
->VarStoreId
);
1645 // Only for Buffer storage need to save the default info in the storage.
1646 // Other type storage, just return.
1648 if (VarStoreType
!= EFI_VFR_VARSTORE_BUFFER
) {
1651 VarInfo
.mInfo
.mVarOffset
= QuestionHead
->VarStoreInfo
.VarOffset
;
1652 VarInfo
.mVarStoreId
= QuestionHead
->VarStoreId
;
1656 // Get the buffer storage info about this question.
1658 gCVfrDataStorage
.GetBufferVarStoreFieldInfo (&VarInfo
);
1663 gCVfrDefaultStore
.BufferVarStoreAltConfigAdd (
1674 Record the number and default id of all defaultstore opcode.
1678 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1683 EFI_IFR_OP_HEADER
*pOpHead
;
1684 EFI_IFR_DEFAULTSTORE
*DefaultStore
;
1686 pNode
= mIfrRecordListHead
;
1687 mAllDefaultTypeCount
= 0;
1689 while (pNode
!= NULL
) {
1690 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1692 if (pOpHead
->OpCode
== EFI_IFR_DEFAULTSTORE_OP
){
1693 DefaultStore
= (EFI_IFR_DEFAULTSTORE
*) pNode
->mIfrBinBuf
;
1694 mAllDefaultIdArray
[mAllDefaultTypeCount
++] = DefaultStore
->DefaultId
;
1696 pNode
= pNode
->mNext
;
1701 Create new default opcode record.
1703 @param Size The new default opcode size.
1704 @param DefaultId The new default id.
1705 @param Type The new default type.
1706 @param LineNo The line number of the new record.
1707 @param Value The new default value.
1711 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1713 IN UINT16 DefaultId
,
1716 IN EFI_IFR_TYPE_VALUE Value
1720 CIfrDefault2
*DObj2
;
1725 if (Type
== EFI_IFR_TYPE_OTHER
) {
1726 DObj2
= new CIfrDefault2 (Size
);
1727 DObj2
->SetDefaultId(DefaultId
);
1728 DObj2
->SetType(Type
);
1729 DObj2
->SetLineNo(LineNo
);
1730 DObj2
->SetScope (1);
1733 DObj
= new CIfrDefault (Size
);
1734 DObj
->SetDefaultId(DefaultId
);
1735 DObj
->SetType(Type
);
1736 DObj
->SetLineNo(LineNo
);
1737 DObj
->SetValue (Value
);
1743 Create new default opcode for question base on the QuestionDefaultInfo.
1745 @param pQuestionNode Point to the question opcode Node.
1746 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1750 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1751 IN SIfrRecord
*pQuestionNode
,
1752 IN QuestionDefaultRecord
*QuestionDefaultInfo
1755 EFI_IFR_OP_HEADER
*pOpHead
;
1756 EFI_IFR_DEFAULT
*Default
;
1759 SIfrRecord
*pDefaultNode
;
1766 EFI_IFR_ONE_OF_OPTION
*DefaultOptionOpcode
;
1767 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue
;
1769 CheckBoxDefaultValue
.b
= 1;
1770 pOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1776 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1778 gAdjustOpcodeOffset
= pQuestionNode
->mNext
->mOffset
;
1781 // For oneof, the default with smallest default id is given by the option flag.
1782 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1784 if (pOpHead
->OpCode
== EFI_IFR_ONE_OF_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1785 DefaultOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)QuestionDefaultInfo
->mDefaultValueRecord
->mIfrBinBuf
;
1786 DefaultSize
= QuestionDefaultInfo
->mDefaultValueRecord
->mBinBufLen
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
);
1787 DefaultSize
+= OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1788 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1789 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1790 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], DefaultOptionOpcode
->Type
, pQuestionNode
->mLineNo
, DefaultOptionOpcode
->Value
);
1792 // Save the new created default in the buffer storage.
1794 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, DefaultOptionOpcode
->Value
);
1802 // For checkbox, the default with smallest default id is given by the question flag.
1803 // And create the missing defaults with true value.
1805 if (pOpHead
-> OpCode
== EFI_IFR_CHECKBOX_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1806 DefaultSize
= OFFSET_OF (EFI_IFR_DEFAULT
, Value
) + sizeof (BOOLEAN
);
1807 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1808 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1809 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], EFI_IFR_TYPE_BOOLEAN
, pQuestionNode
->mLineNo
, CheckBoxDefaultValue
);
1811 // Save the new created default.
1813 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, CheckBoxDefaultValue
);
1821 // The default with smallest default id is given by the default opcode.
1822 // So create the missing defaults base on the value in the default opcode.
1826 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1828 pDefaultNode
= QuestionDefaultInfo
->mDefaultValueRecord
;
1829 Default
= (EFI_IFR_DEFAULT
*)pDefaultNode
->mIfrBinBuf
;
1831 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1833 gAdjustOpcodeOffset
= pDefaultNode
->mNext
->mOffset
;
1835 if (Default
->Type
== EFI_IFR_TYPE_OTHER
) {
1837 // EFI_IFR_DEFAULT_2 opcode.
1839 // Point to the first expression opcode.
1841 pSNode
= pDefaultNode
->mNext
;
1844 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1846 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& ScopeCount
!= 0) {
1847 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1848 if (pOpHead
->Scope
== 1) {
1851 if (pOpHead
->OpCode
== EFI_IFR_END_OP
) {
1855 pSNode
= pSNode
->mNext
;
1859 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1861 gAdjustOpcodeOffset
= pSNode
->mOffset
;
1863 // Create new default opcode node for missing default.
1865 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1866 OpcodeNumber
= OpcodeCount
;
1867 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1868 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pENode
->mLineNo
, Default
->Value
);
1870 // Point to the first expression opcode node.
1872 pSNode
= pDefaultNode
->mNext
;
1874 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1876 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& OpcodeNumber
-- != 0) {
1877 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1878 Obj
= new CIfrObj (pOpHead
->OpCode
, NULL
, pSNode
->mBinBufLen
, FALSE
);
1879 Obj
->SetLineNo (pSNode
->mLineNo
);
1880 ObjBinBuf
= Obj
->GetObjBinAddr();
1881 memcpy (ObjBinBuf
, pSNode
->mIfrBinBuf
, (UINTN
)pSNode
->mBinBufLen
);
1883 pSNode
= pSNode
->mNext
;
1889 // EFI_IFR_DEFAULT opcode.
1891 // Create new default opcode node for missing default.
1893 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1894 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1895 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pDefaultNode
->mLineNo
, Default
->Value
);
1897 // Save the new created default in the buffer storage..
1899 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, Default
->Value
);
1906 Parse the default information in a question, get the QuestionDefaultInfo.
1908 @param pQuestionNode Point to the question record Node.
1909 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1912 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1913 IN SIfrRecord
*pQuestionNode
,
1914 OUT QuestionDefaultRecord
*QuestionDefaultInfo
1918 EFI_IFR_ONE_OF_OPTION
*OneofOptionOpcode
;
1919 EFI_IFR_OP_HEADER
*pSOpHead
;
1920 EFI_IFR_CHECKBOX
*CheckBoxOpcode
;
1921 EFI_IFR_DEFAULT
*DefaultOpcode
;
1922 BOOLEAN IsOneOfOpcode
;
1923 UINT16 SmallestDefaultId
;
1926 SmallestDefaultId
= 0xffff;
1927 IsOneOfOpcode
= FALSE
;
1929 pSNode
= pQuestionNode
;
1932 // Parse all the opcodes in the Question.
1934 while (pSNode
!= NULL
) {
1935 pSOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1937 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1938 // Scopes may be nested within other scopes.
1939 // When finishing parsing a question, the scope count must be zero.
1941 if (pSOpHead
->Scope
== 1) {
1944 if (pSOpHead
->OpCode
== EFI_IFR_END_OP
) {
1948 // Check whether finishing parsing a question.
1950 if (ScopeCount
== 0) {
1955 // Record the default information in the question.
1957 switch (pSOpHead
->OpCode
) {
1958 case EFI_IFR_ONE_OF_OP
:
1959 IsOneOfOpcode
= TRUE
;
1961 case EFI_IFR_CHECKBOX_OP
:
1963 // The default info of check box may be given by flag.
1964 // So need to check the flag of check box.
1966 CheckBoxOpcode
= (EFI_IFR_CHECKBOX
*)pSNode
->mIfrBinBuf
;
1967 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0) {
1969 // Check whether need to update the smallest default id.
1971 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
1972 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
1975 // Update the QuestionDefaultInfo.
1977 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1978 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
1979 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1980 QuestionDefaultInfo
->mDefaultNumber
++;
1981 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
1987 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0) {
1989 // Check whether need to update the smallest default id.
1991 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1992 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
1995 // Update the QuestionDefaultInfo.
1997 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1998 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1999 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2000 QuestionDefaultInfo
->mDefaultNumber
++;
2001 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2008 case EFI_IFR_ONE_OF_OPTION_OP
:
2009 if (!IsOneOfOpcode
) {
2011 // Only check the option in oneof.
2015 OneofOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)pSNode
->mIfrBinBuf
;
2016 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2018 // The option is used as the standard default.
2019 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2021 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2022 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2023 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2026 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2028 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2029 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2030 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2031 QuestionDefaultInfo
->mDefaultNumber
++;
2032 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2038 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0) {
2040 // This option is used as the manufacture default.
2041 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2043 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2044 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2045 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2048 // Update the QuestionDefaultInfo.
2050 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2051 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2052 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2053 QuestionDefaultInfo
->mDefaultNumber
++;
2054 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2061 case EFI_IFR_DEFAULT_OP
:
2062 DefaultOpcode
= (EFI_IFR_DEFAULT
*) pSNode
->mIfrBinBuf
;
2064 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2066 if (SmallestDefaultId
>= DefaultOpcode
->DefaultId
) {
2067 SmallestDefaultId
= DefaultOpcode
->DefaultId
;
2068 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2069 QuestionDefaultInfo
->mIsDefaultOpcode
= TRUE
;
2072 // Update the QuestionDefaultInfo.
2074 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++){
2075 if (mAllDefaultIdArray
[i
] == ((EFI_IFR_DEFAULT
*)pSNode
->mIfrBinBuf
)->DefaultId
) {
2076 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2077 QuestionDefaultInfo
->mDefaultNumber
++;
2078 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2088 // Parse next opcode in this question.
2090 pSNode
= pSNode
->mNext
;
2095 Check or add default for question if need.
2097 This function will check the default info for question.
2098 If the question has default, but the default number < defaultstore opcode number.
2099 will do following two action :
2101 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2102 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2104 We assume that the two options can not be TRUE at same time.
2105 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2107 @param AutoDefault Add default for question if needed
2108 @param CheckDefault Check the default info, if missing default, generates an error.
2112 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2113 BOOLEAN AutoDefault
,
2114 BOOLEAN CheckDefault
2118 SIfrRecord
*pTailNode
;
2119 SIfrRecord
*pStartAdjustNode
;
2120 EFI_IFR_OP_HEADER
*pOpHead
;
2121 QuestionDefaultRecord QuestionDefaultInfo
;
2122 UINT8 MissingDefaultCount
;
2123 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
2125 pNode
= mIfrRecordListHead
;
2128 // Record the number and default id of all defaultstore opcode.
2130 IfrGetDefaultStoreInfo ();
2132 while (pNode
!= NULL
) {
2133 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
2135 // Check whether is question opcode.
2137 if (CheckQuestionOpCode (pOpHead
->OpCode
)) {
2139 // Initialize some local variables here, because they vary with question.
2140 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2142 memset (&QuestionDefaultInfo
, 0, sizeof (QuestionDefaultRecord
));
2143 pTailNode
= mIfrRecordListTail
;
2145 // Get the QuestionDefaultInfo for current question.
2147 IfrParseDefaulInfoInQuestion (pNode
, &QuestionDefaultInfo
);
2149 if (QuestionDefaultInfo
.mDefaultNumber
!= mAllDefaultTypeCount
&& QuestionDefaultInfo
.mDefaultNumber
!= 0) {
2152 // Create default for question which misses default.
2154 IfrCreateDefaultForQuestion (pNode
, &QuestionDefaultInfo
);
2157 // Adjust the buffer content.
2158 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2159 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2161 pStartAdjustNode
=GetRecordInfoFromOffset (gAdjustOpcodeOffset
);
2162 gCFormPkg
.AdjustDynamicInsertOpcode (pStartAdjustNode
->mIfrBinBuf
, pTailNode
->mNext
->mIfrBinBuf
, TRUE
);
2165 // Update the record info.
2167 IfrUpdateRecordInfoForDynamicOpcode (TRUE
);
2168 } else if (CheckDefault
) {
2170 // Generate an error for question which misses default.
2172 MissingDefaultCount
= mAllDefaultTypeCount
- QuestionDefaultInfo
.mDefaultNumber
;
2173 sprintf (Msg
, "The question misses %d default, the question's opcode is %d", MissingDefaultCount
, pOpHead
->OpCode
);
2174 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, NULL
, "Error", Msg
);
2179 // parse next opcode.
2181 pNode
= pNode
->mNext
;
2185 CIfrRecordInfoDB gCIfrRecordInfoDB
;
2188 CIfrObj::_EMIT_PENDING_OBJ (
2192 CHAR8
*ObjBinBuf
= NULL
;
2197 if (!mDelayEmit
|| !gCreateOp
) {
2201 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2203 // update data buffer to package data
2205 ObjBinBuf
= gCFormPkg
.IfrBinBufferGet (mObjBinLen
);
2206 if (ObjBinBuf
!= NULL
) {
2207 memmove (ObjBinBuf
, mObjBinBuf
, mObjBinLen
);
2211 // update bin buffer to package data buffer
2213 if (mObjBinBuf
!= NULL
) {
2215 mObjBinBuf
= ObjBinBuf
;
2222 * The definition of CIfrObj's member function
2227 } gOpcodeSizesScopeTable
[] = {
2228 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2229 { sizeof (EFI_IFR_FORM
), 1 }, // EFI_IFR_FORM_OP
2230 { sizeof (EFI_IFR_SUBTITLE
), 1 }, // EFI_IFR_SUBTITLE_OP
2231 { sizeof (EFI_IFR_TEXT
), 0 }, // EFI_IFR_TEXT_OP
2232 { sizeof (EFI_IFR_IMAGE
), 0 }, // EFI_IFR_IMAGE_OP
2233 { sizeof (EFI_IFR_ONE_OF
), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2234 { sizeof (EFI_IFR_CHECKBOX
), 1}, // EFI_IFR_CHECKBOX_OP
2235 { sizeof (EFI_IFR_NUMERIC
), 1 }, // EFI_IFR_NUMERIC_OP
2236 { sizeof (EFI_IFR_PASSWORD
), 1 }, // EFI_IFR_PASSWORD_OP
2237 { sizeof (EFI_IFR_ONE_OF_OPTION
), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2238 { sizeof (EFI_IFR_SUPPRESS_IF
), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2239 { sizeof (EFI_IFR_LOCKED
), 0 }, // EFI_IFR_LOCKED_OP
2240 { sizeof (EFI_IFR_ACTION
), 1 }, // EFI_IFR_ACTION_OP
2241 { sizeof (EFI_IFR_RESET_BUTTON
), 1 }, // EFI_IFR_RESET_BUTTON_OP
2242 { sizeof (EFI_IFR_FORM_SET
), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2243 { sizeof (EFI_IFR_REF
), 0 }, // EFI_IFR_REF_OP
2244 { sizeof (EFI_IFR_NO_SUBMIT_IF
), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2245 { sizeof (EFI_IFR_INCONSISTENT_IF
), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2246 { sizeof (EFI_IFR_EQ_ID_VAL
), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2247 { sizeof (EFI_IFR_EQ_ID_ID
), 0 }, // EFI_IFR_EQ_ID_ID_OP
2248 { sizeof (EFI_IFR_EQ_ID_VAL_LIST
), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2249 { sizeof (EFI_IFR_AND
), 0 }, // EFI_IFR_AND_OP
2250 { sizeof (EFI_IFR_OR
), 0 }, // EFI_IFR_OR_OP
2251 { sizeof (EFI_IFR_NOT
), 0 }, // EFI_IFR_NOT_OP
2252 { sizeof (EFI_IFR_RULE
), 1 }, // EFI_IFR_RULE_OP
2253 { sizeof (EFI_IFR_GRAY_OUT_IF
), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2254 { sizeof (EFI_IFR_DATE
), 1 }, // EFI_IFR_DATE_OP
2255 { sizeof (EFI_IFR_TIME
), 1 }, // EFI_IFR_TIME_OP
2256 { sizeof (EFI_IFR_STRING
), 1 }, // EFI_IFR_STRING_OP
2257 { sizeof (EFI_IFR_REFRESH
), 0 }, // EFI_IFR_REFRESH_OP
2258 { sizeof (EFI_IFR_DISABLE_IF
), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2260 { sizeof (EFI_IFR_TO_LOWER
), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2261 { sizeof (EFI_IFR_TO_UPPER
), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2262 { sizeof (EFI_IFR_MAP
), 1 }, // EFI_IFR_MAP - 0x22
2263 { sizeof (EFI_IFR_ORDERED_LIST
), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2264 { sizeof (EFI_IFR_VARSTORE
), 0 }, // EFI_IFR_VARSTORE_OP
2265 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE
), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2266 { sizeof (EFI_IFR_VARSTORE_EFI
), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2267 { sizeof (EFI_IFR_VARSTORE_DEVICE
), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2268 { sizeof (EFI_IFR_VERSION
), 0 }, // EFI_IFR_VERSION_OP - 0x28
2269 { sizeof (EFI_IFR_END
), 0 }, // EFI_IFR_END_OP
2270 { sizeof (EFI_IFR_MATCH
), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2271 { sizeof (EFI_IFR_GET
), 0 }, // EFI_IFR_GET - 0x2B
2272 { sizeof (EFI_IFR_SET
), 0 }, // EFI_IFR_SET - 0x2C
2273 { sizeof (EFI_IFR_READ
), 0 }, // EFI_IFR_READ - 0x2D
2274 { sizeof (EFI_IFR_WRITE
), 0 }, // EFI_IFR_WRITE - 0x2E
2275 { sizeof (EFI_IFR_EQUAL
), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2276 { sizeof (EFI_IFR_NOT_EQUAL
), 0 }, // EFI_IFR_NOT_EQUAL_OP
2277 { sizeof (EFI_IFR_GREATER_THAN
), 0 }, // EFI_IFR_GREATER_THAN_OP
2278 { sizeof (EFI_IFR_GREATER_EQUAL
), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2279 { sizeof (EFI_IFR_LESS_THAN
), 0 }, // EFI_IFR_LESS_THAN_OP
2280 { sizeof (EFI_IFR_LESS_EQUAL
), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2281 { sizeof (EFI_IFR_BITWISE_AND
), 0 }, // EFI_IFR_BITWISE_AND_OP
2282 { sizeof (EFI_IFR_BITWISE_OR
), 0 }, // EFI_IFR_BITWISE_OR_OP
2283 { sizeof (EFI_IFR_BITWISE_NOT
), 0 }, // EFI_IFR_BITWISE_NOT_OP
2284 { sizeof (EFI_IFR_SHIFT_LEFT
), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2285 { sizeof (EFI_IFR_SHIFT_RIGHT
), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2286 { sizeof (EFI_IFR_ADD
), 0 }, // EFI_IFR_ADD_OP - 0x3A
2287 { sizeof (EFI_IFR_SUBTRACT
), 0 }, // EFI_IFR_SUBTRACT_OP
2288 { sizeof (EFI_IFR_MULTIPLY
), 0 }, // EFI_IFR_MULTIPLY_OP
2289 { sizeof (EFI_IFR_DIVIDE
), 0 }, // EFI_IFR_DIVIDE_OP
2290 { sizeof (EFI_IFR_MODULO
), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2291 { sizeof (EFI_IFR_RULE_REF
), 0 }, // EFI_IFR_RULE_REF_OP
2292 { sizeof (EFI_IFR_QUESTION_REF1
), 0 }, // EFI_IFR_QUESTION_REF1_OP
2293 { sizeof (EFI_IFR_QUESTION_REF2
), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2294 { sizeof (EFI_IFR_UINT8
), 0}, // EFI_IFR_UINT8
2295 { sizeof (EFI_IFR_UINT16
), 0}, // EFI_IFR_UINT16
2296 { sizeof (EFI_IFR_UINT32
), 0}, // EFI_IFR_UINT32
2297 { sizeof (EFI_IFR_UINT64
), 0}, // EFI_IFR_UTNT64
2298 { sizeof (EFI_IFR_TRUE
), 0 }, // EFI_IFR_TRUE_OP - 0x46
2299 { sizeof (EFI_IFR_FALSE
), 0 }, // EFI_IFR_FALSE_OP
2300 { sizeof (EFI_IFR_TO_UINT
), 0 }, // EFI_IFR_TO_UINT_OP
2301 { sizeof (EFI_IFR_TO_STRING
), 0 }, // EFI_IFR_TO_STRING_OP
2302 { sizeof (EFI_IFR_TO_BOOLEAN
), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2303 { sizeof (EFI_IFR_MID
), 0 }, // EFI_IFR_MID_OP
2304 { sizeof (EFI_IFR_FIND
), 0 }, // EFI_IFR_FIND_OP
2305 { sizeof (EFI_IFR_TOKEN
), 0 }, // EFI_IFR_TOKEN_OP
2306 { sizeof (EFI_IFR_STRING_REF1
), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2307 { sizeof (EFI_IFR_STRING_REF2
), 0 }, // EFI_IFR_STRING_REF2_OP
2308 { sizeof (EFI_IFR_CONDITIONAL
), 0 }, // EFI_IFR_CONDITIONAL_OP
2309 { sizeof (EFI_IFR_QUESTION_REF3
), 0 }, // EFI_IFR_QUESTION_REF3_OP
2310 { sizeof (EFI_IFR_ZERO
), 0 }, // EFI_IFR_ZERO_OP
2311 { sizeof (EFI_IFR_ONE
), 0 }, // EFI_IFR_ONE_OP
2312 { sizeof (EFI_IFR_ONES
), 0 }, // EFI_IFR_ONES_OP
2313 { sizeof (EFI_IFR_UNDEFINED
), 0 }, // EFI_IFR_UNDEFINED_OP
2314 { sizeof (EFI_IFR_LENGTH
), 0 }, // EFI_IFR_LENGTH_OP
2315 { sizeof (EFI_IFR_DUP
), 0 }, // EFI_IFR_DUP_OP - 0x57
2316 { sizeof (EFI_IFR_THIS
), 0 }, // EFI_IFR_THIS_OP
2317 { sizeof (EFI_IFR_SPAN
), 0 }, // EFI_IFR_SPAN_OP
2318 { sizeof (EFI_IFR_VALUE
), 1 }, // EFI_IFR_VALUE_OP
2319 { sizeof (EFI_IFR_DEFAULT
), 0 }, // EFI_IFR_DEFAULT_OP
2320 { sizeof (EFI_IFR_DEFAULTSTORE
), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2321 { sizeof (EFI_IFR_FORM_MAP
), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2322 { sizeof (EFI_IFR_CATENATE
), 0 }, // EFI_IFR_CATENATE_OP
2323 { sizeof (EFI_IFR_GUID
), 0 }, // EFI_IFR_GUID_OP
2324 { sizeof (EFI_IFR_SECURITY
), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2325 { sizeof (EFI_IFR_MODAL_TAG
), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2326 { sizeof (EFI_IFR_REFRESH_ID
), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2327 { sizeof (EFI_IFR_WARNING_IF
), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2328 { sizeof (EFI_IFR_MATCH2
), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2331 #ifdef CIFROBJ_DEUBG
2334 } gIfrObjPrintDebugTable
[] = {
2335 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2336 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2337 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2338 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2339 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2340 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2341 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2342 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2343 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2344 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2345 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2346 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2347 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2348 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2349 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2350 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2351 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2355 CIFROBJ_DEBUG_PRINT (
2359 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable
[OpCode
].mIfrName
);
2363 #define CIFROBJ_DEBUG_PRINT(OpCode)
2367 BOOLEAN gCreateOp
= TRUE
;
2373 IN BOOLEAN DelayEmit
2376 mDelayEmit
= DelayEmit
;
2377 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2378 mObjBinLen
= (ObjBinLen
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: ObjBinLen
;
2379 mObjBinBuf
= ((DelayEmit
== FALSE
) && (gCreateOp
== TRUE
)) ? gCFormPkg
.IfrBinBufferGet (mObjBinLen
) : new CHAR8
[EFI_IFR_MAX_LENGTH
];
2380 mRecordIdx
= (gCreateOp
== TRUE
) ? gCIfrRecordInfoDB
.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf
, mObjBinLen
, mPkgOffset
) : EFI_IFR_RECORDINFO_IDX_INVALUD
;
2382 if (IfrObj
!= NULL
) {
2383 *IfrObj
= mObjBinBuf
;
2386 CIFROBJ_DEBUG_PRINT (OpCode
);
2393 if ((mDelayEmit
== TRUE
) && ((gCreateOp
== TRUE
))) {
2394 _EMIT_PENDING_OBJ ();
2397 gCIfrRecordInfoDB
.IfrRecordInfoUpdate (mRecordIdx
, mLineNo
, mObjBinBuf
, mObjBinLen
, mPkgOffset
);
2401 * The definition of CIfrObj's member function
2403 UINT8 gScopeCount
= 0;
2405 CIfrOpHeader::CIfrOpHeader (
2409 ) : mHeader ((EFI_IFR_OP_HEADER
*)StartAddr
)
2411 mHeader
->OpCode
= OpCode
;
2412 mHeader
->Length
= (Length
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: Length
;
2413 mHeader
->Scope
= (gOpcodeSizesScopeTable
[OpCode
].mScope
+ gScopeCount
> 0) ? 1 : 0;
2416 CIfrOpHeader::CIfrOpHeader (
2417 IN CIfrOpHeader
&OpHdr
2420 mHeader
= OpHdr
.mHeader
;
2423 UINT32
CIfrFormId::FormIdBitMap
[EFI_FREE_FORM_ID_BITMAP_SIZE
] = {0, };