3 Vfr common library functions.
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.
18 #include "CommonLib.h"
19 #include "VfrUtilityLib.h"
20 #include "VfrFormPkg.h"
23 CVfrBinaryOutput::WriteLine (
26 IN CONST CHAR8
*LineHeader
,
33 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
37 for (Index
= 0; Index
< BlkSize
; Index
++) {
38 if ((Index
% LineBytes
) == 0) {
39 fprintf (pFile
, "\n%s", LineHeader
);
41 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
46 CVfrBinaryOutput::WriteEnd (
49 IN CONST CHAR8
*LineHeader
,
56 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
60 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
61 if ((Index
% LineBytes
) == 0) {
62 fprintf (pFile
, "\n%s", LineHeader
);
64 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
67 if ((Index
% LineBytes
) == 0) {
68 fprintf (pFile
, "\n%s", LineHeader
);
70 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
73 SConfigInfo::SConfigInfo (
77 IN EFI_IFR_TYPE_VALUE Value
82 mWidth
= (UINT16
)Width
;
83 mValue
= new UINT8
[mWidth
];
89 case EFI_IFR_TYPE_NUM_SIZE_8
:
90 memcpy (mValue
, &Value
.u8
, mWidth
);
92 case EFI_IFR_TYPE_NUM_SIZE_16
:
93 memcpy (mValue
, &Value
.u16
, mWidth
);
95 case EFI_IFR_TYPE_NUM_SIZE_32
:
96 memcpy (mValue
, &Value
.u32
, mWidth
);
98 case EFI_IFR_TYPE_NUM_SIZE_64
:
99 memcpy (mValue
, &Value
.u64
, mWidth
);
101 case EFI_IFR_TYPE_BOOLEAN
:
102 memcpy (mValue
, &Value
.b
, mWidth
);
104 case EFI_IFR_TYPE_TIME
:
105 memcpy (mValue
, &Value
.time
, mWidth
);
107 case EFI_IFR_TYPE_DATE
:
108 memcpy (mValue
, &Value
.date
, mWidth
);
110 case EFI_IFR_TYPE_STRING
:
111 memcpy (mValue
, &Value
.string
, mWidth
);
113 case EFI_IFR_TYPE_BUFFER
:
114 memcpy (mValue
, &Value
.u8
, mWidth
);
117 case EFI_IFR_TYPE_OTHER
:
122 SConfigInfo::~SConfigInfo (
126 ARRAY_SAFE_FREE (mValue
);
129 SConfigItem::SConfigItem (
142 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
143 strcpy (mName
, Name
);
148 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
149 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
154 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
160 SConfigItem::SConfigItem (
167 IN EFI_IFR_TYPE_VALUE Value
177 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
178 strcpy (mName
, Name
);
183 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
184 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
189 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
194 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
197 SConfigItem::~SConfigItem (
203 ARRAY_SAFE_FREE (mName
);
204 ARRAY_SAFE_FREE (mGuid
);
205 ARRAY_SAFE_FREE (mId
);
206 while (mInfoStrList
!= NULL
) {
208 mInfoStrList
= mInfoStrList
->mNext
;
210 BUFFER_SAFE_FREE (Info
);
215 CVfrBufferConfig::Register (
223 if (Select (Name
, Guid
) == 0) {
227 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
231 if (mItemListHead
== NULL
) {
232 mItemListHead
= pNew
;
233 mItemListTail
= pNew
;
235 mItemListTail
->mNext
= pNew
;
236 mItemListTail
= pNew
;
244 CVfrBufferConfig::Open (
248 mItemListPos
= mItemListHead
;
252 CVfrBufferConfig::Eof(
256 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
260 CVfrBufferConfig::Select (
268 if (Name
== NULL
|| Guid
== NULL
) {
269 mItemListPos
= mItemListHead
;
272 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
273 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
278 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
281 } else if (p
->mId
!= NULL
) {
294 CVfrBufferConfig::Write (
302 IN EFI_IFR_TYPE_VALUE Value
309 if ((Ret
= Select (Name
, Guid
)) != 0) {
315 if (Select (Name
, Guid
, Id
) != 0) {
316 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
319 if (mItemListHead
== NULL
) {
320 mItemListHead
= pItem
;
321 mItemListTail
= pItem
;
323 mItemListTail
->mNext
= pItem
;
324 mItemListTail
= pItem
;
326 mItemListPos
= pItem
;
328 // tranverse the list to find out if there's already the value for the same offset
329 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
330 if (pInfo
->mOffset
== Offset
) {
334 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
337 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
338 mItemListPos
->mInfoStrList
= pInfo
;
343 if (mItemListHead
== mItemListPos
) {
344 mItemListHead
= mItemListPos
->mNext
;
349 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
352 pItem
->mNext
= mItemListPos
->mNext
;
353 if (mItemListTail
== mItemListPos
) {
354 mItemListTail
= pItem
;
357 mItemListPos
= pItem
->mNext
;
360 case 'i' : // set info
361 if (mItemListPos
->mId
!= NULL
) {
362 delete mItemListPos
->mId
;
364 mItemListPos
->mId
= NULL
;
366 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
369 strcpy (mItemListPos
->mId
, Id
);
382 CVfrBufferConfig::Close (
389 #define BYTES_PRE_LINE 0x10
392 CVfrBufferConfig::OutputCFile (
397 CVfrBinaryOutput Output
;
406 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
407 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
410 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
412 TotalLen
= sizeof (UINT32
);
413 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
414 TotalLen
+= sizeof (UINT16
) * 2;
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
418 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
419 fprintf (pFile
, "\n");
420 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
421 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
423 fprintf (pFile
, "\n};\n");
426 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
427 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
428 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
430 TotalLen
= sizeof (UINT32
);
431 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
432 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
436 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
437 fprintf (pFile
, "\n");
438 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
439 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
440 if (Info
->mNext
== NULL
) {
441 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
443 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
446 fprintf (pFile
, "\n};\n");
451 CVfrBufferConfig::CVfrBufferConfig (
455 mItemListHead
= NULL
;
456 mItemListTail
= NULL
;
460 CVfrBufferConfig::~CVfrBufferConfig (
466 while (mItemListHead
!= NULL
) {
468 mItemListHead
= mItemListHead
->mNext
;
472 mItemListHead
= NULL
;
473 mItemListTail
= NULL
;
477 CVfrBufferConfig gCVfrBufferConfig
;
480 CONST CHAR8
*mTypeName
;
484 } gInternalTypesTable
[] = {
485 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
486 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
487 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
488 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
489 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
490 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
491 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
492 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
493 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
494 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
505 if (TypeName
== NULL
) {
509 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
510 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
527 while (*Str
&& *Str
== ' ') {
530 while (*Str
&& *Str
== '0') {
533 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
550 Str
= TrimHex (Str
, &IsHex
);
551 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
553 // BUG: does not handle overflow here
555 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
557 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
558 Value
+= (c
- 'a' + 10);
560 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
561 Value
+= (c
- 'A' + 10);
563 if (c
>= '0' && c
<= '9') {
572 CVfrVarDataTypeDB::RegisterNewType (
576 New
->mNext
= mDataTypeList
;
581 CVfrVarDataTypeDB::ExtractStructTypeName (
587 return VFR_RETURN_FATAL_ERROR
;
590 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
596 if (*VarStr
== '.') {
600 return VFR_RETURN_SUCCESS
;
604 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
611 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
613 ArrayIdx
= INVALID_ARRAY_INDEX
;
616 return VFR_RETURN_FATAL_ERROR
;
619 while((*VarStr
!= '\0') &&
633 return VFR_RETURN_SUCCESS
;
636 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
637 ArrayStr
[Idx
] = *VarStr
;
639 ArrayStr
[Idx
] = '\0';
641 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
642 return VFR_RETURN_DATA_STRING_ERROR
;
644 ArrayIdx
= _STR2U32 (ArrayStr
);
645 if (*VarStr
== ']') {
648 if (*VarStr
== '.') {
651 return VFR_RETURN_SUCCESS
;
653 return VFR_RETURN_DATA_STRING_ERROR
;
656 return VFR_RETURN_SUCCESS
;
660 CVfrVarDataTypeDB::GetTypeField (
661 IN CONST CHAR8
*FName
,
662 IN SVfrDataType
*Type
,
663 OUT SVfrDataField
*&Field
666 SVfrDataField
*pField
= NULL
;
668 if ((FName
== NULL
) || (Type
== NULL
)) {
669 return VFR_RETURN_FATAL_ERROR
;
672 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
674 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
675 // add code to adjust it.
677 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
678 if (strcmp (FName
, "Hour") == 0) {
680 } else if (strcmp (FName
, "Minute") == 0) {
682 } else if (strcmp (FName
, "Second") == 0) {
687 if (strcmp (pField
->mFieldName
, FName
) == 0) {
689 return VFR_RETURN_SUCCESS
;
693 return VFR_RETURN_UNDEFINED
;
697 CVfrVarDataTypeDB::GetFieldOffset (
698 IN SVfrDataField
*Field
,
704 return VFR_RETURN_FATAL_ERROR
;
708 // Framework Vfr file Array Index is from 1.
709 // But Uefi Vfr file Array Index is from 0.
711 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
713 return VFR_RETURN_ERROR_ARRARY_NUM
;
715 ArrayIdx
= ArrayIdx
- 1;
718 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
719 return VFR_RETURN_ERROR_ARRARY_NUM
;
723 // Be compatible with the current usage
724 // If ArraryIdx is not specified, the first one is used.
726 // if ArrayNum is larger than zero, ArraryIdx must be specified.
728 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
729 // return VFR_RETURN_ERROR_ARRARY_NUM;
733 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
734 return VFR_RETURN_SUCCESS
;
738 CVfrVarDataTypeDB::GetFieldWidth (
739 IN SVfrDataField
*Field
746 return Field
->mFieldType
->mType
;
750 CVfrVarDataTypeDB::GetFieldSize (
751 IN SVfrDataField
*Field
,
756 return VFR_RETURN_FATAL_ERROR
;
759 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
760 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
762 return Field
->mFieldType
->mTotalSize
;
767 CVfrVarDataTypeDB::InternalTypesListInit (
771 SVfrDataType
*New
= NULL
;
774 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
775 New
= new SVfrDataType
;
777 strcpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
);
778 New
->mType
= gInternalTypesTable
[Index
].mType
;
779 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
780 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
781 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
782 SVfrDataField
*pYearField
= new SVfrDataField
;
783 SVfrDataField
*pMonthField
= new SVfrDataField
;
784 SVfrDataField
*pDayField
= new SVfrDataField
;
786 strcpy (pYearField
->mFieldName
, "Year");
787 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
788 pYearField
->mOffset
= 0;
789 pYearField
->mNext
= pMonthField
;
790 pYearField
->mArrayNum
= 0;
792 strcpy (pMonthField
->mFieldName
, "Month");
793 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
794 pMonthField
->mOffset
= 2;
795 pMonthField
->mNext
= pDayField
;
796 pMonthField
->mArrayNum
= 0;
798 strcpy (pDayField
->mFieldName
, "Day");
799 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
800 pDayField
->mOffset
= 3;
801 pDayField
->mNext
= NULL
;
802 pDayField
->mArrayNum
= 0;
804 New
->mMembers
= pYearField
;
805 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
806 SVfrDataField
*pHoursField
= new SVfrDataField
;
807 SVfrDataField
*pMinutesField
= new SVfrDataField
;
808 SVfrDataField
*pSecondsField
= new SVfrDataField
;
810 strcpy (pHoursField
->mFieldName
, "Hours");
811 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
812 pHoursField
->mOffset
= 0;
813 pHoursField
->mNext
= pMinutesField
;
814 pHoursField
->mArrayNum
= 0;
816 strcpy (pMinutesField
->mFieldName
, "Minutes");
817 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
818 pMinutesField
->mOffset
= 1;
819 pMinutesField
->mNext
= pSecondsField
;
820 pMinutesField
->mArrayNum
= 0;
822 strcpy (pSecondsField
->mFieldName
, "Seconds");
823 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
824 pSecondsField
->mOffset
= 2;
825 pSecondsField
->mNext
= NULL
;
826 pSecondsField
->mArrayNum
= 0;
828 New
->mMembers
= pHoursField
;
829 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
830 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
831 SVfrDataField
*pFormIdField
= new SVfrDataField
;
832 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
833 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
835 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
836 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
837 pQuestionIdField
->mOffset
= 0;
838 pQuestionIdField
->mNext
= pFormIdField
;
839 pQuestionIdField
->mArrayNum
= 0;
841 strcpy (pFormIdField
->mFieldName
, "FormId");
842 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
843 pFormIdField
->mOffset
= 2;
844 pFormIdField
->mNext
= pFormSetGuidField
;
845 pFormIdField
->mArrayNum
= 0;
847 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
848 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
849 pFormSetGuidField
->mOffset
= 4;
850 pFormSetGuidField
->mNext
= pDevicePathField
;
851 pFormSetGuidField
->mArrayNum
= 0;
853 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
854 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
855 pDevicePathField
->mOffset
= 20;
856 pDevicePathField
->mNext
= NULL
;
857 pDevicePathField
->mArrayNum
= 0;
859 New
->mMembers
= pQuestionIdField
;
861 New
->mMembers
= NULL
;
864 RegisterNewType (New
);
870 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
874 mDataTypeList
= NULL
;
876 mCurrDataField
= NULL
;
877 mPackAlign
= DEFAULT_PACK_ALIGN
;
879 mFirstNewDataTypeName
= NULL
;
881 InternalTypesListInit ();
884 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
889 SVfrDataField
*pField
;
890 SVfrPackStackNode
*pPack
;
892 if (mNewDataType
!= NULL
) {
896 while (mDataTypeList
!= NULL
) {
897 pType
= mDataTypeList
;
898 mDataTypeList
= mDataTypeList
->mNext
;
899 while(pType
->mMembers
!= NULL
) {
900 pField
= pType
->mMembers
;
901 pType
->mMembers
= pType
->mMembers
->mNext
;
907 while (mPackStack
!= NULL
) {
909 mPackStack
= mPackStack
->mNext
;
915 CVfrVarDataTypeDB::Pack (
918 IN CHAR8
*Identifier
,
923 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
925 if (Action
& VFR_PACK_SHOW
) {
926 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
927 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
930 if (Action
& VFR_PACK_PUSH
) {
931 SVfrPackStackNode
*pNew
= NULL
;
933 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
934 return VFR_RETURN_FATAL_ERROR
;
936 pNew
->mNext
= mPackStack
;
940 if (Action
& VFR_PACK_POP
) {
941 SVfrPackStackNode
*pNode
= NULL
;
943 if (mPackStack
== NULL
) {
944 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
947 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
948 if (pNode
->Match (Identifier
) == TRUE
) {
949 mPackAlign
= pNode
->mNumber
;
950 mPackStack
= pNode
->mNext
;
955 if (Action
& VFR_PACK_ASSIGN
) {
956 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
957 if ((PackAlign
== 0) || (PackAlign
> 16)) {
958 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
960 mPackAlign
= PackAlign
;
964 return VFR_RETURN_SUCCESS
;
968 CVfrVarDataTypeDB::DeclareDataTypeBegin (
972 SVfrDataType
*pNewType
= NULL
;
974 pNewType
= new SVfrDataType
;
975 pNewType
->mTypeName
[0] = '\0';
976 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
977 pNewType
->mAlign
= DEFAULT_ALIGN
;
978 pNewType
->mTotalSize
= 0;
979 pNewType
->mMembers
= NULL
;
980 pNewType
->mNext
= NULL
;
982 mNewDataType
= pNewType
;
986 CVfrVarDataTypeDB::SetNewTypeName (
992 if (mNewDataType
== NULL
) {
993 return VFR_RETURN_ERROR_SKIPED
;
995 if (TypeName
== NULL
) {
996 return VFR_RETURN_FATAL_ERROR
;
998 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
999 return VFR_RETURN_INVALID_PARAMETER
;
1002 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1003 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1004 return VFR_RETURN_REDEFINED
;
1008 strcpy(mNewDataType
->mTypeName
, TypeName
);
1009 return VFR_RETURN_SUCCESS
;
1013 CVfrVarDataTypeDB::DataTypeAddField (
1014 IN CHAR8
*FieldName
,
1019 SVfrDataField
*pNewField
= NULL
;
1020 SVfrDataType
*pFieldType
= NULL
;
1021 SVfrDataField
*pTmp
;
1024 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1026 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1027 return VFR_RETURN_INVALID_PARAMETER
;
1030 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1031 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1032 return VFR_RETURN_REDEFINED
;
1036 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1038 if ((pNewField
= new SVfrDataField
) == NULL
) {
1039 return VFR_RETURN_OUT_FOR_RESOURCES
;
1041 strcpy (pNewField
->mFieldName
, FieldName
);
1042 pNewField
->mFieldType
= pFieldType
;
1043 pNewField
->mArrayNum
= ArrayNum
;
1044 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1045 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1047 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1049 if (mNewDataType
->mMembers
== NULL
) {
1050 mNewDataType
->mMembers
= pNewField
;
1051 pNewField
->mNext
= NULL
;
1053 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1055 pTmp
->mNext
= pNewField
;
1056 pNewField
->mNext
= NULL
;
1059 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1060 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1062 return VFR_RETURN_SUCCESS
;
1066 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1070 if (mNewDataType
->mTypeName
[0] == '\0') {
1074 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1075 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1078 RegisterNewType (mNewDataType
);
1079 if (mFirstNewDataTypeName
== NULL
) {
1080 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1083 mNewDataType
= NULL
;
1087 CVfrVarDataTypeDB::GetDataType (
1089 OUT SVfrDataType
**DataType
1092 SVfrDataType
*pDataType
= NULL
;
1094 if (TypeName
== NULL
) {
1095 return VFR_RETURN_ERROR_SKIPED
;
1098 if (DataType
== NULL
) {
1099 return VFR_RETURN_FATAL_ERROR
;
1104 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1105 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1106 *DataType
= pDataType
;
1107 return VFR_RETURN_SUCCESS
;
1111 return VFR_RETURN_UNDEFINED
;
1115 CVfrVarDataTypeDB::GetDataTypeSize (
1120 SVfrDataType
*pDataType
= NULL
;
1123 return VFR_RETURN_FATAL_ERROR
;
1127 DataType
= DataType
& 0x0F;
1130 // For user defined data type, the size can't be got by this function.
1132 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1133 return VFR_RETURN_SUCCESS
;
1136 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1137 if (DataType
== pDataType
->mType
) {
1138 *Size
= pDataType
->mTotalSize
;
1139 return VFR_RETURN_SUCCESS
;
1143 return VFR_RETURN_UNDEFINED
;
1147 CVfrVarDataTypeDB::GetDataTypeSize (
1152 SVfrDataType
*pDataType
= NULL
;
1155 return VFR_RETURN_FATAL_ERROR
;
1160 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1161 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1162 *Size
= pDataType
->mTotalSize
;
1163 return VFR_RETURN_SUCCESS
;
1167 return VFR_RETURN_UNDEFINED
;
1171 CVfrVarDataTypeDB::GetDataFieldInfo (
1178 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1179 UINT32 ArrayIdx
, Tmp
;
1180 SVfrDataType
*pType
= NULL
;
1181 SVfrDataField
*pField
= NULL
;
1184 Type
= EFI_IFR_TYPE_OTHER
;
1187 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1188 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1191 // if it is not struct data type
1193 Type
= pType
->mType
;
1194 Size
= pType
->mTotalSize
;
1196 while (*VarStr
!= '\0') {
1197 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1198 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1199 pType
= pField
->mFieldType
;
1200 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1201 Offset
= (UINT16
) (Offset
+ Tmp
);
1202 Type
= GetFieldWidth (pField
);
1203 Size
= GetFieldSize (pField
, ArrayIdx
);
1205 return VFR_RETURN_SUCCESS
;
1209 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1210 OUT CHAR8
***NameList
,
1211 OUT UINT32
*ListSize
1215 SVfrDataType
*pType
;
1217 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1218 return VFR_RETURN_FATAL_ERROR
;
1224 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1225 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1230 if (*ListSize
== 0) {
1231 return VFR_RETURN_SUCCESS
;
1234 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1236 return VFR_RETURN_OUT_FOR_RESOURCES
;
1239 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1240 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1241 (*NameList
)[Index
] = pType
->mTypeName
;
1244 return VFR_RETURN_SUCCESS
;
1248 CVfrVarDataTypeDB::IsTypeNameDefined (
1252 SVfrDataType
*pType
;
1254 if (TypeName
== NULL
) {
1258 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1259 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1268 CVfrVarDataTypeDB::Dump (
1272 SVfrDataType
*pTNode
;
1273 SVfrDataField
*pFNode
;
1275 fprintf (File
, "\n\n***************************************************************\n");
1276 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1277 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1278 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1279 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1280 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1281 if (pFNode
->mArrayNum
> 0) {
1282 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1283 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1285 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1286 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1289 fprintf (File
, "\t\t};\n");
1290 fprintf (File
, "---------------------------------------------------------------\n");
1292 fprintf (File
, "***************************************************************\n");
1295 #ifdef CVFR_VARDATATYPEDB_DEBUG
1297 CVfrVarDataTypeDB::ParserDB (
1301 SVfrDataType
*pTNode
;
1302 SVfrDataField
*pFNode
;
1304 printf ("***************************************************************\n");
1305 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1306 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1307 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1308 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1309 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1310 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1312 printf ("\t\t};\n");
1313 printf ("---------------------------------------------------------------\n");
1315 printf ("***************************************************************\n");
1319 SVfrVarStorageNode::SVfrVarStorageNode (
1321 IN CHAR8
*StoreName
,
1322 IN EFI_VARSTORE_ID VarStoreId
,
1323 IN EFI_STRING_ID VarName
,
1331 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1333 if (StoreName
!= NULL
) {
1334 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1335 strcpy (mVarStoreName
, StoreName
);
1337 mVarStoreName
= NULL
;
1340 mVarStoreId
= VarStoreId
;
1341 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1342 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1343 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1344 mAssignedFlag
= Flag
;
1347 SVfrVarStorageNode::SVfrVarStorageNode (
1349 IN CHAR8
*StoreName
,
1350 IN EFI_VARSTORE_ID VarStoreId
,
1351 IN SVfrDataType
*DataType
,
1358 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1360 if (StoreName
!= NULL
) {
1361 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1362 strcpy (mVarStoreName
, StoreName
);
1364 mVarStoreName
= NULL
;
1367 mVarStoreId
= VarStoreId
;
1368 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1369 mStorageInfo
.mDataType
= DataType
;
1370 mAssignedFlag
= Flag
;
1373 SVfrVarStorageNode::SVfrVarStorageNode (
1374 IN CHAR8
*StoreName
,
1375 IN EFI_VARSTORE_ID VarStoreId
1378 if (StoreName
!= NULL
) {
1379 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1380 strcpy (mVarStoreName
, StoreName
);
1382 mVarStoreName
= NULL
;
1385 mVarStoreId
= VarStoreId
;
1386 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1387 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1388 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1391 SVfrVarStorageNode::~SVfrVarStorageNode (
1395 if (mVarStoreName
!= NULL
) {
1396 delete[] mVarStoreName
;
1399 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1400 delete mStorageInfo
.mNameSpace
.mNameTable
;
1404 CVfrDataStorage::CVfrDataStorage (
1410 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1411 mFreeVarStoreIdBitMap
[Index
] = 0;
1414 // Question ID 0 is reserved.
1415 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1417 mBufferVarStoreList
= NULL
;
1418 mEfiVarStoreList
= NULL
;
1419 mNameVarStoreList
= NULL
;
1420 mCurrVarStorageNode
= NULL
;
1421 mNewVarStorageNode
= NULL
;
1422 mBufferFieldInfoListHead
= NULL
;
1423 mBufferFieldInfoListTail
= NULL
;
1426 CVfrDataStorage::~CVfrDataStorage (
1430 SVfrVarStorageNode
*pNode
;
1432 while (mBufferVarStoreList
!= NULL
) {
1433 pNode
= mBufferVarStoreList
;
1434 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1437 while (mEfiVarStoreList
!= NULL
) {
1438 pNode
= mEfiVarStoreList
;
1439 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1442 while (mNameVarStoreList
!= NULL
) {
1443 pNode
= mNameVarStoreList
;
1444 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1447 if (mNewVarStorageNode
!= NULL
) {
1448 delete mNewVarStorageNode
;
1453 CVfrDataStorage::GetFreeVarStoreId (
1454 EFI_VFR_VARSTORE_TYPE VarType
1457 UINT32 Index
, Mask
, Offset
;
1460 // Assign the different ID range for the different type VarStore to support Framework Vfr
1463 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1465 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1467 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1471 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1472 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1477 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1478 return EFI_VARSTORE_ID_INVALID
;
1481 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1482 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1483 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1484 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1488 return EFI_VARSTORE_ID_INVALID
;
1492 CVfrDataStorage::ChekVarStoreIdFree (
1493 IN EFI_VARSTORE_ID VarStoreId
1496 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1497 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1499 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1503 CVfrDataStorage::MarkVarStoreIdUsed (
1504 IN EFI_VARSTORE_ID VarStoreId
1507 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1508 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1510 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1514 CVfrDataStorage::MarkVarStoreIdUnused (
1515 IN EFI_VARSTORE_ID VarStoreId
1518 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1519 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1521 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1525 CVfrDataStorage::DeclareNameVarStoreBegin (
1526 IN CHAR8
*StoreName
,
1527 IN EFI_VARSTORE_ID VarStoreId
1530 SVfrVarStorageNode
*pNode
= NULL
;
1531 EFI_VARSTORE_ID TmpVarStoreId
;
1533 if (StoreName
== NULL
) {
1534 return VFR_RETURN_FATAL_ERROR
;
1537 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1538 return VFR_RETURN_REDEFINED
;
1541 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1542 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1544 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1545 return VFR_RETURN_VARSTOREID_REDEFINED
;
1547 MarkVarStoreIdUsed (VarStoreId
);
1550 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1551 return VFR_RETURN_UNDEFINED
;
1554 mNewVarStorageNode
= pNode
;
1556 return VFR_RETURN_SUCCESS
;
1560 CVfrDataStorage::NameTableAddItem (
1561 IN EFI_STRING_ID Item
1564 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1567 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1568 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1570 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1571 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1572 return VFR_RETURN_OUT_FOR_RESOURCES
;
1574 memcpy (NewTable
, OldTable
, TableSize
);
1575 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1578 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1579 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1581 return VFR_RETURN_SUCCESS
;
1585 CVfrDataStorage::DeclareNameVarStoreEnd (
1589 mNewVarStorageNode
->mGuid
= *Guid
;
1590 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1591 mNameVarStoreList
= mNewVarStorageNode
;
1593 mNewVarStorageNode
= NULL
;
1595 return VFR_RETURN_SUCCESS
;
1599 CVfrDataStorage::DeclareEfiVarStore (
1600 IN CHAR8
*StoreName
,
1602 IN EFI_STRING_ID NameStrId
,
1607 SVfrVarStorageNode
*pNode
;
1608 EFI_VARSTORE_ID VarStoreId
;
1610 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1611 return VFR_RETURN_FATAL_ERROR
;
1614 if (VarSize
> sizeof (UINT64
)) {
1615 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1618 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1619 return VFR_RETURN_REDEFINED
;
1622 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1623 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1624 return VFR_RETURN_OUT_FOR_RESOURCES
;
1627 pNode
->mNext
= mEfiVarStoreList
;
1628 mEfiVarStoreList
= pNode
;
1630 return VFR_RETURN_SUCCESS
;
1634 CVfrDataStorage::DeclareBufferVarStore (
1635 IN CHAR8
*StoreName
,
1637 IN CVfrVarDataTypeDB
*DataTypeDB
,
1639 IN EFI_VARSTORE_ID VarStoreId
,
1643 SVfrVarStorageNode
*pNew
= NULL
;
1644 SVfrDataType
*pDataType
= NULL
;
1645 EFI_VARSTORE_ID TempVarStoreId
;
1647 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1648 return VFR_RETURN_FATAL_ERROR
;
1651 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1652 return VFR_RETURN_REDEFINED
;
1655 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1657 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1658 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1660 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1661 return VFR_RETURN_VARSTOREID_REDEFINED
;
1663 MarkVarStoreIdUsed (VarStoreId
);
1666 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1667 return VFR_RETURN_OUT_FOR_RESOURCES
;
1670 pNew
->mNext
= mBufferVarStoreList
;
1671 mBufferVarStoreList
= pNew
;
1673 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1674 return VFR_RETURN_FATAL_ERROR
;
1677 return VFR_RETURN_SUCCESS
;
1681 CVfrDataStorage::GetVarStoreByDataType (
1682 IN CHAR8
*DataTypeName
,
1683 OUT SVfrVarStorageNode
**VarNode
,
1684 IN EFI_GUID
*VarGuid
1687 SVfrVarStorageNode
*pNode
;
1688 SVfrVarStorageNode
*MatchNode
;
1691 // Framework VFR uses Data type name as varstore name, so don't need check again.
1693 if (VfrCompatibleMode
) {
1694 return VFR_RETURN_UNDEFINED
;
1698 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1699 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1703 if ((VarGuid
!= NULL
)) {
1704 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1706 return VFR_RETURN_SUCCESS
;
1709 if (MatchNode
== NULL
) {
1713 // More than one varstores referred the same data structures.
1715 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1720 if (MatchNode
== NULL
) {
1721 return VFR_RETURN_UNDEFINED
;
1724 *VarNode
= MatchNode
;
1725 return VFR_RETURN_SUCCESS
;
1729 CVfrDataStorage::CheckGuidField (
1730 IN SVfrVarStorageNode
*pNode
,
1731 IN EFI_GUID
*StoreGuid
,
1732 IN BOOLEAN
*HasFoundOne
,
1733 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1736 if (StoreGuid
!= NULL
) {
1738 // If has guid info, compare the guid filed.
1740 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1742 // Both name and guid are same, this this varstore.
1744 mCurrVarStorageNode
= pNode
;
1745 *ReturnCode
= VFR_RETURN_SUCCESS
;
1750 // Not has Guid field, check whether this name is the only one.
1754 // The name has conflict, return name redefined.
1756 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1760 *HasFoundOne
= TRUE
;
1761 mCurrVarStorageNode
= pNode
;
1768 Base on the input store name and guid to find the varstore id.
1770 If both name and guid are inputed, base on the name and guid to
1771 found the varstore. If only name inputed, base on the name to
1772 found the varstore and go on to check whether more than one varstore
1773 has the same name. If only has found one varstore, return this
1774 varstore; if more than one varstore has same name, return varstore
1775 name redefined error. If no varstore found by varstore name, call
1776 function GetVarStoreByDataType and use inputed varstore name as
1777 data type name to search.
1780 CVfrDataStorage::GetVarStoreId (
1781 IN CHAR8
*StoreName
,
1782 OUT EFI_VARSTORE_ID
*VarStoreId
,
1783 IN EFI_GUID
*StoreGuid
1786 EFI_VFR_RETURN_CODE ReturnCode
;
1787 SVfrVarStorageNode
*pNode
;
1788 BOOLEAN HasFoundOne
= FALSE
;
1790 mCurrVarStorageNode
= NULL
;
1792 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1793 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1794 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1795 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1801 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1802 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1803 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1804 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1810 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1811 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1812 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1813 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1820 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1821 return VFR_RETURN_SUCCESS
;
1824 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1827 // Assume that Data strucutre name is used as StoreName, and check again.
1829 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1830 if (pNode
!= NULL
) {
1831 mCurrVarStorageNode
= pNode
;
1832 *VarStoreId
= pNode
->mVarStoreId
;
1839 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1840 IN EFI_VARSTORE_ID VarStoreId
,
1841 OUT CHAR8
**DataTypeName
1844 SVfrVarStorageNode
*pNode
;
1846 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1847 return VFR_RETURN_FATAL_ERROR
;
1850 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1851 if (pNode
->mVarStoreId
== VarStoreId
) {
1852 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1853 return VFR_RETURN_SUCCESS
;
1857 return VFR_RETURN_UNDEFINED
;
1860 EFI_VFR_VARSTORE_TYPE
1861 CVfrDataStorage::GetVarStoreType (
1862 IN EFI_VARSTORE_ID VarStoreId
1865 SVfrVarStorageNode
*pNode
;
1866 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1868 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1870 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1871 return VarStoreType
;
1874 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1875 if (pNode
->mVarStoreId
== VarStoreId
) {
1876 VarStoreType
= pNode
->mVarStoreType
;
1877 return VarStoreType
;
1881 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1882 if (pNode
->mVarStoreId
== VarStoreId
) {
1883 VarStoreType
= pNode
->mVarStoreType
;
1884 return VarStoreType
;
1888 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1889 if (pNode
->mVarStoreId
== VarStoreId
) {
1890 VarStoreType
= pNode
->mVarStoreType
;
1891 return VarStoreType
;
1895 return VarStoreType
;
1899 CVfrDataStorage::GetVarStoreGuid (
1900 IN EFI_VARSTORE_ID VarStoreId
1903 SVfrVarStorageNode
*pNode
;
1908 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1912 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1913 if (pNode
->mVarStoreId
== VarStoreId
) {
1914 VarGuid
= &pNode
->mGuid
;
1919 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1920 if (pNode
->mVarStoreId
== VarStoreId
) {
1921 VarGuid
= &pNode
->mGuid
;
1926 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1927 if (pNode
->mVarStoreId
== VarStoreId
) {
1928 VarGuid
= &pNode
->mGuid
;
1937 CVfrDataStorage::GetVarStoreName (
1938 IN EFI_VARSTORE_ID VarStoreId
,
1939 OUT CHAR8
**VarStoreName
1942 SVfrVarStorageNode
*pNode
;
1944 if (VarStoreName
== NULL
) {
1945 return VFR_RETURN_FATAL_ERROR
;
1948 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1949 if (pNode
->mVarStoreId
== VarStoreId
) {
1950 *VarStoreName
= pNode
->mVarStoreName
;
1951 return VFR_RETURN_SUCCESS
;
1955 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1956 if (pNode
->mVarStoreId
== VarStoreId
) {
1957 *VarStoreName
= pNode
->mVarStoreName
;
1958 return VFR_RETURN_SUCCESS
;
1962 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1963 if (pNode
->mVarStoreId
== VarStoreId
) {
1964 *VarStoreName
= pNode
->mVarStoreName
;
1965 return VFR_RETURN_SUCCESS
;
1969 *VarStoreName
= NULL
;
1970 return VFR_RETURN_UNDEFINED
;
1974 CVfrDataStorage::GetEfiVarStoreInfo (
1975 IN OUT EFI_VARSTORE_INFO
*Info
1979 return VFR_RETURN_FATAL_ERROR
;
1982 if (mCurrVarStorageNode
== NULL
) {
1983 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1986 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1987 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1988 switch (Info
->mVarTotalSize
) {
1990 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1993 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1996 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1999 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2002 return VFR_RETURN_FATAL_ERROR
;
2005 return VFR_RETURN_SUCCESS
;
2009 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2010 IN EFI_VARSTORE_INFO
*Info
2013 BufferVarStoreFieldInfoNode
*pNew
;
2015 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2016 return VFR_RETURN_FATAL_ERROR
;
2019 if (mBufferFieldInfoListHead
== NULL
) {
2020 mBufferFieldInfoListHead
= pNew
;
2021 mBufferFieldInfoListTail
= pNew
;
2023 mBufferFieldInfoListTail
->mNext
= pNew
;
2024 mBufferFieldInfoListTail
= pNew
;
2027 return VFR_RETURN_SUCCESS
;
2031 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2032 IN OUT EFI_VARSTORE_INFO
*Info
2035 BufferVarStoreFieldInfoNode
*pNode
;
2037 pNode
= mBufferFieldInfoListHead
;
2038 while (pNode
!= NULL
) {
2039 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2040 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2041 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2042 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2043 return VFR_RETURN_SUCCESS
;
2045 pNode
= pNode
->mNext
;
2047 return VFR_RETURN_FATAL_ERROR
;
2051 CVfrDataStorage::GetNameVarStoreInfo (
2052 OUT EFI_VARSTORE_INFO
*Info
,
2057 return VFR_RETURN_FATAL_ERROR
;
2060 if (mCurrVarStorageNode
== NULL
) {
2061 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2065 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2067 if (VfrCompatibleMode
) {
2069 return VFR_RETURN_ERROR_ARRARY_NUM
;
2074 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2076 return VFR_RETURN_SUCCESS
;
2079 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2080 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2082 IN EFI_STRING_ID DefaultStoreNameId
,
2086 mObjBinAddr
= ObjBinAddr
;
2088 if (RefName
!= NULL
) {
2089 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2090 strcpy (mRefName
, RefName
);
2096 mDefaultId
= DefaultId
;
2097 mDefaultStoreNameId
= DefaultStoreNameId
;
2100 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2104 if (mRefName
!= NULL
) {
2109 CVfrDefaultStore::CVfrDefaultStore (
2113 mDefaultStoreList
= NULL
;
2116 CVfrDefaultStore::~CVfrDefaultStore (
2120 SVfrDefaultStoreNode
*pTmp
= NULL
;
2122 while (mDefaultStoreList
!= NULL
) {
2123 pTmp
= mDefaultStoreList
;
2124 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2130 CVfrDefaultStore::RegisterDefaultStore (
2131 IN CHAR8
*ObjBinAddr
,
2133 IN EFI_STRING_ID DefaultStoreNameId
,
2137 SVfrDefaultStoreNode
*pNode
= NULL
;
2139 if (RefName
== NULL
) {
2140 return VFR_RETURN_FATAL_ERROR
;
2143 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2144 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2145 return VFR_RETURN_REDEFINED
;
2149 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2150 return VFR_RETURN_OUT_FOR_RESOURCES
;
2153 pNode
->mNext
= mDefaultStoreList
;
2154 mDefaultStoreList
= pNode
;
2156 return VFR_RETURN_SUCCESS
;
2160 * assign new reference name or new default store name id only if
2161 * the original is invalid
2164 CVfrDefaultStore::ReRegisterDefaultStoreById (
2165 IN UINT16 DefaultId
,
2167 IN EFI_STRING_ID DefaultStoreNameId
2170 SVfrDefaultStoreNode
*pNode
= NULL
;
2172 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2173 if (pNode
->mDefaultId
== DefaultId
) {
2178 if (pNode
== NULL
) {
2179 return VFR_RETURN_UNDEFINED
;
2181 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2182 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2183 if (pNode
->mObjBinAddr
!= NULL
) {
2184 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2187 return VFR_RETURN_REDEFINED
;
2190 if (RefName
!= NULL
) {
2191 delete pNode
->mRefName
;
2192 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2193 if (pNode
->mRefName
!= NULL
) {
2194 strcpy (pNode
->mRefName
, RefName
);
2199 return VFR_RETURN_SUCCESS
;
2203 CVfrDefaultStore::DefaultIdRegistered (
2207 SVfrDefaultStoreNode
*pNode
= NULL
;
2209 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2210 if (pNode
->mDefaultId
== DefaultId
) {
2219 CVfrDefaultStore::GetDefaultId (
2221 OUT UINT16
*DefaultId
2224 SVfrDefaultStoreNode
*pTmp
= NULL
;
2226 if (DefaultId
== NULL
) {
2227 return VFR_RETURN_FATAL_ERROR
;
2230 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2231 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2232 *DefaultId
= pTmp
->mDefaultId
;
2233 return VFR_RETURN_SUCCESS
;
2237 return VFR_RETURN_UNDEFINED
;
2241 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2242 IN EFI_VARSTORE_ID DefaultId
,
2243 IN EFI_VARSTORE_INFO
&Info
,
2244 IN CHAR8
*VarStoreName
,
2245 IN EFI_GUID
*VarStoreGuid
,
2247 IN EFI_IFR_TYPE_VALUE Value
2250 SVfrDefaultStoreNode
*pNode
= NULL
;
2251 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2252 INTN Returnvalue
= 0;
2254 if (VarStoreName
== NULL
) {
2255 return VFR_RETURN_FATAL_ERROR
;
2258 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2259 if (pNode
->mDefaultId
== DefaultId
) {
2264 if (pNode
== NULL
) {
2265 return VFR_RETURN_UNDEFINED
;
2268 gCVfrBufferConfig
.Open ();
2270 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2271 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2272 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2277 gCVfrBufferConfig
.Close ();
2279 return VFR_RETURN_SUCCESS
;
2282 gCVfrBufferConfig
.Close ();
2283 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2286 SVfrRuleNode::SVfrRuleNode (
2291 if (RuleName
!= NULL
) {
2292 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2293 strcpy (mRuleName
, RuleName
);
2302 SVfrRuleNode::~SVfrRuleNode (
2306 if (mRuleName
!= NULL
) {
2311 CVfrRulesDB::CVfrRulesDB ()
2314 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2317 CVfrRulesDB::~CVfrRulesDB ()
2319 SVfrRuleNode
*pNode
;
2321 while(mRuleList
!= NULL
) {
2323 mRuleList
= mRuleList
->mNext
;
2329 CVfrRulesDB::RegisterRule (
2335 if (RuleName
== NULL
) {
2339 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2345 pNew
->mNext
= mRuleList
;
2350 CVfrRulesDB::GetRuleId (
2354 SVfrRuleNode
*pNode
;
2356 if (RuleName
== NULL
) {
2357 return EFI_RULE_ID_INVALID
;
2360 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2361 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2362 return pNode
->mRuleId
;
2366 return EFI_RULE_ID_INVALID
;
2369 CVfrRulesDB gCVfrRulesDB
;
2371 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2375 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2376 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2377 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2378 mVarType
= EFI_IFR_TYPE_OTHER
;
2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2383 IN EFI_VARSTORE_INFO
&Info
2386 mVarStoreId
= Info
.mVarStoreId
;
2387 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2388 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2389 mVarType
= Info
.mVarType
;
2390 mVarTotalSize
= Info
.mVarTotalSize
;
2394 EFI_VARSTORE_INFO::operator == (
2395 IN EFI_VARSTORE_INFO
*Info
2398 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2399 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2400 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2401 (mVarType
== Info
->mVarType
) &&
2402 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2409 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2410 IN EFI_VARSTORE_INFO
*Info
2413 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2414 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2415 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2416 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2420 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2422 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2423 mVarStoreInfo
.mVarTotalSize
= 0;
2424 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2425 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2429 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2432 CVfrQuestionDB::GetFreeQuestionId (
2436 UINT32 Index
, Mask
, Offset
;
2438 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2439 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2444 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2445 return EFI_QUESTION_ID_INVALID
;
2448 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2449 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2450 mFreeQIdBitMap
[Index
] |= Mask
;
2451 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2455 return EFI_QUESTION_ID_INVALID
;
2459 CVfrQuestionDB::ChekQuestionIdFree (
2460 IN EFI_QUESTION_ID QId
2463 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2464 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2466 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2470 CVfrQuestionDB::MarkQuestionIdUsed (
2471 IN EFI_QUESTION_ID QId
2474 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2475 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2477 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2481 CVfrQuestionDB::MarkQuestionIdUnused (
2482 IN EFI_QUESTION_ID QId
2485 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2486 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2488 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2491 SVfrQuestionNode::SVfrQuestionNode (
2499 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2502 mQtype
= QUESTION_NORMAL
;
2505 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2506 strcpy (mName
, "$DEFAULT");
2508 mName
= new CHAR8
[strlen (Name
) + 1];
2509 strcpy (mName
, Name
);
2512 if (VarIdStr
!= NULL
) {
2513 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2514 strcpy (mVarIdStr
, VarIdStr
);
2516 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2517 strcpy (mVarIdStr
, "$");
2521 SVfrQuestionNode::~SVfrQuestionNode (
2525 if (mName
!= NULL
) {
2529 if (mVarIdStr
!= NULL
) {
2534 CVfrQuestionDB::CVfrQuestionDB ()
2538 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2539 mFreeQIdBitMap
[Index
] = 0;
2542 // Question ID 0 is reserved.
2543 mFreeQIdBitMap
[0] = 0x80000000;
2544 mQuestionList
= NULL
;
2547 CVfrQuestionDB::~CVfrQuestionDB ()
2549 SVfrQuestionNode
*pNode
;
2551 while (mQuestionList
!= NULL
) {
2552 pNode
= mQuestionList
;
2553 mQuestionList
= mQuestionList
->mNext
;
2559 // Reset to init state
2562 CVfrQuestionDB::ResetInit(
2567 SVfrQuestionNode
*pNode
;
2569 while (mQuestionList
!= NULL
) {
2570 pNode
= mQuestionList
;
2571 mQuestionList
= mQuestionList
->mNext
;
2575 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2576 mFreeQIdBitMap
[Index
] = 0;
2579 // Question ID 0 is reserved.
2580 mFreeQIdBitMap
[0] = 0x80000000;
2581 mQuestionList
= NULL
;
2585 CVfrQuestionDB::PrintAllQuestion (
2589 SVfrQuestionNode
*pNode
= NULL
;
2591 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2592 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2597 CVfrQuestionDB::RegisterQuestion (
2600 IN OUT EFI_QUESTION_ID
&QuestionId
2603 SVfrQuestionNode
*pNode
= NULL
;
2605 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2606 return VFR_RETURN_REDEFINED
;
2609 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2610 return VFR_RETURN_OUT_FOR_RESOURCES
;
2613 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2614 QuestionId
= GetFreeQuestionId ();
2617 // For Framework Vfr, don't check question ID conflict.
2619 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2621 return VFR_RETURN_QUESTIONID_REDEFINED
;
2623 MarkQuestionIdUsed (QuestionId
);
2625 pNode
->mQuestionId
= QuestionId
;
2627 pNode
->mNext
= mQuestionList
;
2628 mQuestionList
= pNode
;
2630 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2632 return VFR_RETURN_SUCCESS
;
2636 CVfrQuestionDB::RegisterOldDateQuestion (
2637 IN CHAR8
*YearVarId
,
2638 IN CHAR8
*MonthVarId
,
2640 IN OUT EFI_QUESTION_ID
&QuestionId
2643 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2646 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2650 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2653 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2656 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2660 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2661 QuestionId
= GetFreeQuestionId ();
2663 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2666 MarkQuestionIdUsed (QuestionId
);
2669 pNode
[0]->mQuestionId
= QuestionId
;
2670 pNode
[1]->mQuestionId
= QuestionId
;
2671 pNode
[2]->mQuestionId
= QuestionId
;
2672 pNode
[0]->mQtype
= QUESTION_DATE
;
2673 pNode
[1]->mQtype
= QUESTION_DATE
;
2674 pNode
[2]->mQtype
= QUESTION_DATE
;
2675 pNode
[0]->mNext
= pNode
[1];
2676 pNode
[1]->mNext
= pNode
[2];
2677 pNode
[2]->mNext
= mQuestionList
;
2678 mQuestionList
= pNode
[0];
2680 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2681 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2682 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2687 for (Index
= 0; Index
< 3; Index
++) {
2688 if (pNode
[Index
] != NULL
) {
2689 delete pNode
[Index
];
2692 QuestionId
= EFI_QUESTION_ID_INVALID
;
2696 CVfrQuestionDB::RegisterNewDateQuestion (
2698 IN CHAR8
*BaseVarId
,
2699 IN OUT EFI_QUESTION_ID
&QuestionId
2702 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2704 CHAR8
*VarIdStr
[3] = {NULL
, };
2707 if (BaseVarId
== NULL
&& Name
== NULL
) {
2708 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2709 QuestionId
= GetFreeQuestionId ();
2711 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2714 MarkQuestionIdUsed (QuestionId
);
2719 if (BaseVarId
!= NULL
) {
2720 Len
= strlen (BaseVarId
);
2722 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2723 if (VarIdStr
[0] != NULL
) {
2724 strcpy (VarIdStr
[0], BaseVarId
);
2725 strcat (VarIdStr
[0], ".Year");
2727 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2728 if (VarIdStr
[1] != NULL
) {
2729 strcpy (VarIdStr
[1], BaseVarId
);
2730 strcat (VarIdStr
[1], ".Month");
2732 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2733 if (VarIdStr
[2] != NULL
) {
2734 strcpy (VarIdStr
[2], BaseVarId
);
2735 strcat (VarIdStr
[2], ".Day");
2738 Len
= strlen (Name
);
2740 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2741 if (VarIdStr
[0] != NULL
) {
2742 strcpy (VarIdStr
[0], Name
);
2743 strcat (VarIdStr
[0], ".Year");
2745 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2746 if (VarIdStr
[1] != NULL
) {
2747 strcpy (VarIdStr
[1], Name
);
2748 strcat (VarIdStr
[1], ".Month");
2750 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2751 if (VarIdStr
[2] != NULL
) {
2752 strcpy (VarIdStr
[2], Name
);
2753 strcat (VarIdStr
[2], ".Day");
2757 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2760 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2763 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2767 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2768 QuestionId
= GetFreeQuestionId ();
2770 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2773 MarkQuestionIdUsed (QuestionId
);
2776 pNode
[0]->mQuestionId
= QuestionId
;
2777 pNode
[1]->mQuestionId
= QuestionId
;
2778 pNode
[2]->mQuestionId
= QuestionId
;
2779 pNode
[0]->mQtype
= QUESTION_DATE
;
2780 pNode
[1]->mQtype
= QUESTION_DATE
;
2781 pNode
[2]->mQtype
= QUESTION_DATE
;
2782 pNode
[0]->mNext
= pNode
[1];
2783 pNode
[1]->mNext
= pNode
[2];
2784 pNode
[2]->mNext
= mQuestionList
;
2785 mQuestionList
= pNode
[0];
2787 for (Index
= 0; Index
< 3; Index
++) {
2788 if (VarIdStr
[Index
] != NULL
) {
2789 delete VarIdStr
[Index
];
2793 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2794 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2795 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2800 for (Index
= 0; Index
< 3; Index
++) {
2801 if (pNode
[Index
] != NULL
) {
2802 delete pNode
[Index
];
2805 if (VarIdStr
[Index
] != NULL
) {
2806 delete VarIdStr
[Index
];
2812 CVfrQuestionDB::RegisterOldTimeQuestion (
2813 IN CHAR8
*HourVarId
,
2814 IN CHAR8
*MinuteVarId
,
2815 IN CHAR8
*SecondVarId
,
2816 IN OUT EFI_QUESTION_ID
&QuestionId
2819 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2822 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2826 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2829 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2832 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2836 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2837 QuestionId
= GetFreeQuestionId ();
2839 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2842 MarkQuestionIdUsed (QuestionId
);
2845 pNode
[0]->mQuestionId
= QuestionId
;
2846 pNode
[1]->mQuestionId
= QuestionId
;
2847 pNode
[2]->mQuestionId
= QuestionId
;
2848 pNode
[0]->mQtype
= QUESTION_TIME
;
2849 pNode
[1]->mQtype
= QUESTION_TIME
;
2850 pNode
[2]->mQtype
= QUESTION_TIME
;
2851 pNode
[0]->mNext
= pNode
[1];
2852 pNode
[1]->mNext
= pNode
[2];
2853 pNode
[2]->mNext
= mQuestionList
;
2854 mQuestionList
= pNode
[0];
2856 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2857 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2858 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2863 for (Index
= 0; Index
< 3; Index
++) {
2864 if (pNode
[Index
] != NULL
) {
2865 delete pNode
[Index
];
2868 QuestionId
= EFI_QUESTION_ID_INVALID
;
2872 CVfrQuestionDB::RegisterNewTimeQuestion (
2874 IN CHAR8
*BaseVarId
,
2875 IN OUT EFI_QUESTION_ID
&QuestionId
2878 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2880 CHAR8
*VarIdStr
[3] = {NULL
, };
2883 if (BaseVarId
== NULL
&& Name
== NULL
) {
2884 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2885 QuestionId
= GetFreeQuestionId ();
2887 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2890 MarkQuestionIdUsed (QuestionId
);
2895 if (BaseVarId
!= NULL
) {
2896 Len
= strlen (BaseVarId
);
2898 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2899 if (VarIdStr
[0] != NULL
) {
2900 strcpy (VarIdStr
[0], BaseVarId
);
2901 strcat (VarIdStr
[0], ".Hour");
2903 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2904 if (VarIdStr
[1] != NULL
) {
2905 strcpy (VarIdStr
[1], BaseVarId
);
2906 strcat (VarIdStr
[1], ".Minute");
2908 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2909 if (VarIdStr
[2] != NULL
) {
2910 strcpy (VarIdStr
[2], BaseVarId
);
2911 strcat (VarIdStr
[2], ".Second");
2914 Len
= strlen (Name
);
2916 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2917 if (VarIdStr
[0] != NULL
) {
2918 strcpy (VarIdStr
[0], Name
);
2919 strcat (VarIdStr
[0], ".Hour");
2921 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2922 if (VarIdStr
[1] != NULL
) {
2923 strcpy (VarIdStr
[1], Name
);
2924 strcat (VarIdStr
[1], ".Minute");
2926 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2927 if (VarIdStr
[2] != NULL
) {
2928 strcpy (VarIdStr
[2], Name
);
2929 strcat (VarIdStr
[2], ".Second");
2933 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2936 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2939 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2943 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2944 QuestionId
= GetFreeQuestionId ();
2946 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2949 MarkQuestionIdUsed (QuestionId
);
2952 pNode
[0]->mQuestionId
= QuestionId
;
2953 pNode
[1]->mQuestionId
= QuestionId
;
2954 pNode
[2]->mQuestionId
= QuestionId
;
2955 pNode
[0]->mQtype
= QUESTION_TIME
;
2956 pNode
[1]->mQtype
= QUESTION_TIME
;
2957 pNode
[2]->mQtype
= QUESTION_TIME
;
2958 pNode
[0]->mNext
= pNode
[1];
2959 pNode
[1]->mNext
= pNode
[2];
2960 pNode
[2]->mNext
= mQuestionList
;
2961 mQuestionList
= pNode
[0];
2963 for (Index
= 0; Index
< 3; Index
++) {
2964 if (VarIdStr
[Index
] != NULL
) {
2965 delete VarIdStr
[Index
];
2969 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2970 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2971 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2976 for (Index
= 0; Index
< 3; Index
++) {
2977 if (pNode
[Index
] != NULL
) {
2978 delete pNode
[Index
];
2981 if (VarIdStr
[Index
] != NULL
) {
2982 delete VarIdStr
[Index
];
2988 CVfrQuestionDB::RegisterRefQuestion (
2990 IN CHAR8
*BaseVarId
,
2991 IN OUT EFI_QUESTION_ID
&QuestionId
2994 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2996 CHAR8
*VarIdStr
[4] = {NULL
, };
2999 if (BaseVarId
== NULL
&& Name
== NULL
) {
3003 if (BaseVarId
!= NULL
) {
3004 Len
= strlen (BaseVarId
);
3006 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3007 if (VarIdStr
[0] != NULL
) {
3008 strcpy (VarIdStr
[0], BaseVarId
);
3009 strcat (VarIdStr
[0], ".QuestionId");
3011 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3012 if (VarIdStr
[1] != NULL
) {
3013 strcpy (VarIdStr
[1], BaseVarId
);
3014 strcat (VarIdStr
[1], ".FormId");
3016 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3017 if (VarIdStr
[2] != NULL
) {
3018 strcpy (VarIdStr
[2], BaseVarId
);
3019 strcat (VarIdStr
[2], ".FormSetGuid");
3021 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3022 if (VarIdStr
[3] != NULL
) {
3023 strcpy (VarIdStr
[3], BaseVarId
);
3024 strcat (VarIdStr
[3], ".DevicePath");
3027 Len
= strlen (Name
);
3029 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3030 if (VarIdStr
[0] != NULL
) {
3031 strcpy (VarIdStr
[0], Name
);
3032 strcat (VarIdStr
[0], ".QuestionId");
3034 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3035 if (VarIdStr
[1] != NULL
) {
3036 strcpy (VarIdStr
[1], Name
);
3037 strcat (VarIdStr
[1], ".FormId");
3039 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3040 if (VarIdStr
[2] != NULL
) {
3041 strcpy (VarIdStr
[2], Name
);
3042 strcat (VarIdStr
[2], ".FormSetGuid");
3044 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3045 if (VarIdStr
[3] != NULL
) {
3046 strcpy (VarIdStr
[3], Name
);
3047 strcat (VarIdStr
[3], ".DevicePath");
3051 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3054 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3057 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3060 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3064 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3065 QuestionId
= GetFreeQuestionId ();
3067 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3070 MarkQuestionIdUsed (QuestionId
);
3073 pNode
[0]->mQuestionId
= QuestionId
;
3074 pNode
[1]->mQuestionId
= QuestionId
;
3075 pNode
[2]->mQuestionId
= QuestionId
;
3076 pNode
[3]->mQuestionId
= QuestionId
;
3077 pNode
[0]->mQtype
= QUESTION_REF
;
3078 pNode
[1]->mQtype
= QUESTION_REF
;
3079 pNode
[2]->mQtype
= QUESTION_REF
;
3080 pNode
[3]->mQtype
= QUESTION_REF
;
3081 pNode
[0]->mNext
= pNode
[1];
3082 pNode
[1]->mNext
= pNode
[2];
3083 pNode
[2]->mNext
= pNode
[3];
3084 pNode
[3]->mNext
= mQuestionList
;
3085 mQuestionList
= pNode
[0];
3087 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3088 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3089 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3090 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3095 for (Index
= 0; Index
< 4; Index
++) {
3096 if (pNode
[Index
] != NULL
) {
3097 delete pNode
[Index
];
3100 if (VarIdStr
[Index
] != NULL
) {
3101 delete VarIdStr
[Index
];
3107 CVfrQuestionDB::UpdateQuestionId (
3108 IN EFI_QUESTION_ID QId
,
3109 IN EFI_QUESTION_ID NewQId
3112 SVfrQuestionNode
*pNode
= NULL
;
3114 if (QId
== NewQId
) {
3116 return VFR_RETURN_SUCCESS
;
3120 // For Framework Vfr, don't check question ID conflict.
3122 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3123 return VFR_RETURN_REDEFINED
;
3126 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3127 if (pNode
->mQuestionId
== QId
) {
3132 if (pNode
== NULL
) {
3133 return VFR_RETURN_UNDEFINED
;
3136 MarkQuestionIdUnused (QId
);
3137 pNode
->mQuestionId
= NewQId
;
3138 MarkQuestionIdUsed (NewQId
);
3140 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3142 return VFR_RETURN_SUCCESS
;
3146 CVfrQuestionDB::GetQuestionId (
3149 OUT EFI_QUESTION_ID
&QuestionId
,
3150 OUT UINT32
&BitMask
,
3151 OUT EFI_QUESION_TYPE
*QType
3154 SVfrQuestionNode
*pNode
;
3156 QuestionId
= EFI_QUESTION_ID_INVALID
;
3157 BitMask
= 0x00000000;
3158 if (QType
!= NULL
) {
3159 *QType
= QUESTION_NORMAL
;
3162 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3166 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3168 if (strcmp (pNode
->mName
, Name
) != 0) {
3173 if (VarIdStr
!= NULL
) {
3174 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3179 QuestionId
= pNode
->mQuestionId
;
3180 BitMask
= pNode
->mBitMask
;
3181 if (QType
!= NULL
) {
3182 *QType
= pNode
->mQtype
;
3191 CVfrQuestionDB::FindQuestion (
3192 IN EFI_QUESTION_ID QuestionId
3195 SVfrQuestionNode
*pNode
;
3197 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3198 return VFR_RETURN_INVALID_PARAMETER
;
3201 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3202 if (pNode
->mQuestionId
== QuestionId
) {
3203 return VFR_RETURN_SUCCESS
;
3207 return VFR_RETURN_UNDEFINED
;
3211 CVfrQuestionDB::FindQuestion (
3215 SVfrQuestionNode
*pNode
;
3218 return VFR_RETURN_FATAL_ERROR
;
3221 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3222 if (strcmp (pNode
->mName
, Name
) == 0) {
3223 return VFR_RETURN_SUCCESS
;
3227 return VFR_RETURN_UNDEFINED
;
3230 CVfrStringDB::CVfrStringDB ()
3232 mStringFileName
= NULL
;
3235 CVfrStringDB::~CVfrStringDB ()
3237 if (mStringFileName
!= NULL
) {
3238 delete mStringFileName
;
3240 mStringFileName
= NULL
;
3245 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3249 if (StringFileName
== NULL
) {
3253 FileLen
= strlen (StringFileName
) + 1;
3254 mStringFileName
= new CHAR8
[FileLen
];
3255 if (mStringFileName
== NULL
) {
3259 strcpy (mStringFileName
, StringFileName
);
3260 mStringFileName
[FileLen
- 1] = '\0';
3265 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3266 from a set of supported languages.
3268 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3269 contains a set of language codes.
3270 @param[in] Language A variable that contains pointers to Null-terminated
3271 ASCII strings that contain one language codes.
3273 @retval FALSE The best matching language could not be found in SupportedLanguages.
3274 @retval TRUE The best matching language could be found in SupportedLanguages.
3278 CVfrStringDB::GetBestLanguage (
3279 IN CONST CHAR8
*SupportedLanguages
,
3283 UINTN CompareLength
;
3284 UINTN LanguageLength
;
3285 CONST CHAR8
*Supported
;
3287 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3292 // Determine the length of the first RFC 4646 language code in Language
3294 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3297 // Trim back the length of Language used until it is empty
3299 while (LanguageLength
> 0) {
3301 // Loop through all language codes in SupportedLanguages
3303 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3305 // Skip ';' characters in Supported
3307 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3309 // Determine the length of the next language code in Supported
3311 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3313 // If Language is longer than the Supported, then skip to the next language
3315 if (LanguageLength
> CompareLength
) {
3320 // See if the first LanguageLength characters in Supported match Language
3322 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3328 // Trim Language from the right to the next '-' character
3330 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3334 // No matches were found
3341 CVfrStringDB::GetVarStoreNameFormStringId (
3342 IN EFI_STRING_ID StringId
3345 FILE *pInFile
= NULL
;
3350 CHAR16
*UnicodeString
;
3351 CHAR8
*VarStoreName
= NULL
;
3355 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3357 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3359 if (mStringFileName
== '\0' ) {
3363 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3370 fseek (pInFile
, 0, SEEK_END
);
3371 Length
= ftell (pInFile
);
3372 fseek (pInFile
, 0, SEEK_SET
);
3377 StringPtr
= new UINT8
[Length
];
3378 if (StringPtr
== NULL
) {
3382 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3385 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3387 // Check the String package.
3389 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3395 // Search the language, get best language base on RFC 4647 matching algorithm.
3397 Current
= StringPtr
;
3398 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3399 Current
+= PkgHeader
->Header
.Length
;
3400 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3402 // If can't find string package base on language, just return the first string package.
3404 if (Current
- StringPtr
>= Length
) {
3405 Current
= StringPtr
;
3406 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3411 Current
+= PkgHeader
->HdrSize
;
3413 // Find the string block according the stringId.
3415 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3416 if (Status
!= EFI_SUCCESS
) {
3422 // Get varstore name according the string type.
3424 switch (BlockType
) {
3425 case EFI_HII_SIBT_STRING_SCSU
:
3426 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3427 case EFI_HII_SIBT_STRINGS_SCSU
:
3428 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3429 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3430 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3431 strcpy (VarStoreName
, StringName
);
3433 case EFI_HII_SIBT_STRING_UCS2
:
3434 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3435 case EFI_HII_SIBT_STRINGS_UCS2
:
3436 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3437 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3438 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3439 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3440 VarStoreName
= DestTmp
;
3441 while (*UnicodeString
!= '\0') {
3442 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3452 return VarStoreName
;
3456 CVfrStringDB::FindStringBlock (
3457 IN UINT8
*StringData
,
3458 IN EFI_STRING_ID StringId
,
3459 OUT UINT32
*StringTextOffset
,
3460 OUT UINT8
*BlockType
3464 EFI_STRING_ID CurrentStringId
;
3467 UINT8
*StringTextPtr
;
3472 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3476 CurrentStringId
= 1;
3479 // Parse the string blocks to get the string text and font.
3481 BlockHdr
= StringData
;
3484 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3485 switch (*BlockHdr
) {
3486 case EFI_HII_SIBT_STRING_SCSU
:
3487 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3488 StringTextPtr
= BlockHdr
+ Offset
;
3489 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3493 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3494 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3495 StringTextPtr
= BlockHdr
+ Offset
;
3496 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3500 case EFI_HII_SIBT_STRINGS_SCSU
:
3501 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3502 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3503 BlockSize
+= StringTextPtr
- BlockHdr
;
3505 for (Index
= 0; Index
< StringCount
; Index
++) {
3506 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3507 if (CurrentStringId
== StringId
) {
3508 *BlockType
= *BlockHdr
;
3509 *StringTextOffset
= StringTextPtr
- StringData
;
3512 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3517 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3520 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3523 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3524 BlockSize
+= StringTextPtr
- BlockHdr
;
3526 for (Index
= 0; Index
< StringCount
; Index
++) {
3527 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3528 if (CurrentStringId
== StringId
) {
3529 *BlockType
= *BlockHdr
;
3530 *StringTextOffset
= StringTextPtr
- StringData
;
3533 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3538 case EFI_HII_SIBT_STRING_UCS2
:
3539 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3540 StringTextPtr
= BlockHdr
+ Offset
;
3542 // Use StringSize to store the size of the specified string, including the NULL
3545 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3546 BlockSize
+= Offset
+ StringSize
;
3550 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3551 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3552 StringTextPtr
= BlockHdr
+ Offset
;
3554 // Use StrSize to store the size of the specified string, including the NULL
3557 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3558 BlockSize
+= Offset
+ StringSize
;
3562 case EFI_HII_SIBT_STRINGS_UCS2
:
3563 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3564 StringTextPtr
= BlockHdr
+ Offset
;
3565 BlockSize
+= Offset
;
3566 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3567 for (Index
= 0; Index
< StringCount
; Index
++) {
3568 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3569 BlockSize
+= StringSize
;
3570 if (CurrentStringId
== StringId
) {
3571 *BlockType
= *BlockHdr
;
3572 *StringTextOffset
= StringTextPtr
- StringData
;
3575 StringTextPtr
= StringTextPtr
+ StringSize
;
3580 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3581 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3582 StringTextPtr
= BlockHdr
+ Offset
;
3583 BlockSize
+= Offset
;
3586 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3589 for (Index
= 0; Index
< StringCount
; Index
++) {
3590 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3591 BlockSize
+= StringSize
;
3592 if (CurrentStringId
== StringId
) {
3593 *BlockType
= *BlockHdr
;
3594 *StringTextOffset
= StringTextPtr
- StringData
;
3597 StringTextPtr
= StringTextPtr
+ StringSize
;
3602 case EFI_HII_SIBT_DUPLICATE
:
3603 if (CurrentStringId
== StringId
) {
3605 // Incoming StringId is an id of a duplicate string block.
3606 // Update the StringId to be the previous string block.
3607 // Go back to the header of string block to search.
3611 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3612 sizeof (EFI_STRING_ID
)
3614 CurrentStringId
= 1;
3617 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3622 case EFI_HII_SIBT_SKIP1
:
3623 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3624 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3625 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3628 case EFI_HII_SIBT_SKIP2
:
3629 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3630 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3631 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3634 case EFI_HII_SIBT_EXT1
:
3637 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3640 BlockSize
+= Length8
;
3643 case EFI_HII_SIBT_EXT2
:
3644 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3645 BlockSize
+= Ext2
.Length
;
3648 case EFI_HII_SIBT_EXT4
:
3651 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3655 BlockSize
+= Length32
;
3662 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3663 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3664 *BlockType
= *BlockHdr
;
3666 if (StringId
== CurrentStringId
- 1) {
3668 // if only one skip item, return EFI_NOT_FOUND.
3670 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3671 return EFI_NOT_FOUND
;
3677 if (StringId
< CurrentStringId
- 1) {
3678 return EFI_NOT_FOUND
;
3681 BlockHdr
= StringData
+ BlockSize
;
3684 return EFI_NOT_FOUND
;
3688 CVfrStringDB::GetUnicodeStringTextSize (
3695 StringSize
= sizeof (CHAR16
);
3696 StringPtr
= (UINT16
*)StringSrc
;
3697 while (*StringPtr
++ != L
'\0') {
3698 StringSize
+= sizeof (CHAR16
);
3704 BOOLEAN VfrCompatibleMode
= FALSE
;
3706 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3707 CVfrDefaultStore gCVfrDefaultStore
;
3708 CVfrDataStorage gCVfrDataStorage
;