3 Vfr common library functions.
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include "CommonLib.h"
14 #include "VfrUtilityLib.h"
15 #include "VfrFormPkg.h"
18 CVfrBinaryOutput::WriteLine (
21 IN CONST CHAR8
*LineHeader
,
28 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
32 for (Index
= 0; Index
< BlkSize
; Index
++) {
33 if ((Index
% LineBytes
) == 0) {
34 fprintf (pFile
, "\n%s", LineHeader
);
36 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
41 CVfrBinaryOutput::WriteEnd (
44 IN CONST CHAR8
*LineHeader
,
51 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
55 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
56 if ((Index
% LineBytes
) == 0) {
57 fprintf (pFile
, "\n%s", LineHeader
);
59 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
62 if ((Index
% LineBytes
) == 0) {
63 fprintf (pFile
, "\n%s", LineHeader
);
65 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
68 SConfigInfo::SConfigInfo (
72 IN EFI_IFR_TYPE_VALUE Value
77 mWidth
= (UINT16
)Width
;
78 mValue
= new UINT8
[mWidth
];
84 case EFI_IFR_TYPE_NUM_SIZE_8
:
85 memcpy (mValue
, &Value
.u8
, mWidth
);
87 case EFI_IFR_TYPE_NUM_SIZE_16
:
88 memcpy (mValue
, &Value
.u16
, mWidth
);
90 case EFI_IFR_TYPE_NUM_SIZE_32
:
91 memcpy (mValue
, &Value
.u32
, mWidth
);
93 case EFI_IFR_TYPE_NUM_SIZE_64
:
94 memcpy (mValue
, &Value
.u64
, mWidth
);
96 case EFI_IFR_TYPE_BOOLEAN
:
97 memcpy (mValue
, &Value
.b
, mWidth
);
99 case EFI_IFR_TYPE_TIME
:
100 memcpy (mValue
, &Value
.time
, mWidth
);
102 case EFI_IFR_TYPE_DATE
:
103 memcpy (mValue
, &Value
.date
, mWidth
);
105 case EFI_IFR_TYPE_STRING
:
106 memcpy (mValue
, &Value
.string
, mWidth
);
108 case EFI_IFR_TYPE_BUFFER
:
109 memcpy (mValue
, &Value
.u8
, mWidth
);
112 case EFI_IFR_TYPE_OTHER
:
117 SConfigInfo::~SConfigInfo (
121 ARRAY_SAFE_FREE (mValue
);
124 SConfigItem::SConfigItem (
137 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
138 strcpy (mName
, Name
);
143 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
144 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
149 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
155 SConfigItem::SConfigItem (
162 IN EFI_IFR_TYPE_VALUE Value
172 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
173 strcpy (mName
, Name
);
178 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
179 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
184 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
189 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
192 SConfigItem::~SConfigItem (
198 ARRAY_SAFE_FREE (mName
);
199 ARRAY_SAFE_FREE (mGuid
);
200 ARRAY_SAFE_FREE (mId
);
201 while (mInfoStrList
!= NULL
) {
203 mInfoStrList
= mInfoStrList
->mNext
;
205 BUFFER_SAFE_FREE (Info
);
210 CVfrBufferConfig::Register (
218 if (Select (Name
, Guid
) == 0) {
222 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
226 if (mItemListHead
== NULL
) {
227 mItemListHead
= pNew
;
228 mItemListTail
= pNew
;
230 mItemListTail
->mNext
= pNew
;
231 mItemListTail
= pNew
;
239 CVfrBufferConfig::Open (
243 mItemListPos
= mItemListHead
;
247 CVfrBufferConfig::Eof(
251 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
255 CVfrBufferConfig::Select (
263 if (Name
== NULL
|| Guid
== NULL
) {
264 mItemListPos
= mItemListHead
;
267 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
268 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
273 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
276 } else if (p
->mId
!= NULL
) {
289 CVfrBufferConfig::Write (
297 IN EFI_IFR_TYPE_VALUE Value
304 if ((Ret
= Select (Name
, Guid
)) != 0) {
310 if (Select (Name
, Guid
, Id
) != 0) {
311 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
314 if (mItemListHead
== NULL
) {
315 mItemListHead
= pItem
;
316 mItemListTail
= pItem
;
318 mItemListTail
->mNext
= pItem
;
319 mItemListTail
= pItem
;
321 mItemListPos
= pItem
;
323 // tranverse the list to find out if there's already the value for the same offset
324 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
325 if (pInfo
->mOffset
== Offset
) {
329 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
332 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
333 mItemListPos
->mInfoStrList
= pInfo
;
338 if (mItemListHead
== mItemListPos
) {
339 mItemListHead
= mItemListPos
->mNext
;
344 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
347 pItem
->mNext
= mItemListPos
->mNext
;
348 if (mItemListTail
== mItemListPos
) {
349 mItemListTail
= pItem
;
352 mItemListPos
= pItem
->mNext
;
355 case 'i' : // set info
356 if (mItemListPos
->mId
!= NULL
) {
357 delete[] mItemListPos
->mId
;
359 mItemListPos
->mId
= NULL
;
361 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
364 strcpy (mItemListPos
->mId
, Id
);
377 CVfrBufferConfig::Close (
384 #define BYTES_PRE_LINE 0x10
387 CVfrBufferConfig::OutputCFile (
392 CVfrBinaryOutput Output
;
401 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
402 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
405 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
407 TotalLen
= sizeof (UINT32
);
408 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
409 TotalLen
+= sizeof (UINT16
) * 2;
411 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
413 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
414 fprintf (pFile
, "\n");
415 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
418 fprintf (pFile
, "\n};\n");
421 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
422 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
423 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
425 TotalLen
= sizeof (UINT32
);
426 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
427 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
429 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
431 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
432 fprintf (pFile
, "\n");
433 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
435 if (Info
->mNext
== NULL
) {
436 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
438 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
441 fprintf (pFile
, "\n};\n");
446 CVfrBufferConfig::CVfrBufferConfig (
450 mItemListHead
= NULL
;
451 mItemListTail
= NULL
;
455 CVfrBufferConfig::~CVfrBufferConfig (
461 while (mItemListHead
!= NULL
) {
463 mItemListHead
= mItemListHead
->mNext
;
467 mItemListHead
= NULL
;
468 mItemListTail
= NULL
;
472 CVfrBufferConfig gCVfrBufferConfig
;
475 CONST CHAR8
*mTypeName
;
479 } gInternalTypesTable
[] = {
480 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
481 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
482 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
483 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
484 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
485 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
486 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
487 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
488 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
489 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
500 if (TypeName
== NULL
) {
504 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
505 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
522 while (*Str
&& *Str
== ' ') {
525 while (*Str
&& *Str
== '0') {
528 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
545 Str
= TrimHex (Str
, &IsHex
);
546 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
548 // BUG: does not handle overflow here
550 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
552 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
553 Value
+= (c
- 'a' + 10);
555 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
556 Value
+= (c
- 'A' + 10);
558 if (c
>= '0' && c
<= '9') {
567 CVfrVarDataTypeDB::RegisterNewType (
571 New
->mNext
= mDataTypeList
;
576 CVfrVarDataTypeDB::ExtractStructTypeName (
582 return VFR_RETURN_FATAL_ERROR
;
585 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
591 if (*VarStr
== '.') {
595 return VFR_RETURN_SUCCESS
;
599 Check whether the DataType contain bit field.
601 @param TypeName The name of the type.
605 CVfrVarDataTypeDB::DataTypeHasBitField (
609 SVfrDataType
*pType
= NULL
;
612 GetDataType (TypeName
, &pType
);
617 for (pTmp
= pType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
618 if (pTmp
->mIsBitField
) {
626 Check whether the field is bit field or not.
628 @param VarStr Point to the field name which may contain the structure name.
632 CVfrVarDataTypeDB::IsThisBitField (
636 CHAR8 FName
[MAX_NAME_LEN
];
637 CHAR8 TName
[MAX_NAME_LEN
];
639 SVfrDataType
*pType
= NULL
;
640 SVfrDataField
*pField
= NULL
;
642 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
643 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
645 while (*VarStr
!= '\0') {
646 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
647 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
648 pType
= pField
->mFieldType
;
650 if (pField
!= NULL
&& pField
->mIsBitField
) {
658 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
665 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
667 ArrayIdx
= INVALID_ARRAY_INDEX
;
670 return VFR_RETURN_FATAL_ERROR
;
673 while((*VarStr
!= '\0') &&
687 return VFR_RETURN_SUCCESS
;
690 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
691 ArrayStr
[Idx
] = *VarStr
;
693 ArrayStr
[Idx
] = '\0';
695 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
696 return VFR_RETURN_DATA_STRING_ERROR
;
698 ArrayIdx
= _STR2U32 (ArrayStr
);
699 if (*VarStr
== ']') {
702 if (*VarStr
== '.') {
705 return VFR_RETURN_SUCCESS
;
707 return VFR_RETURN_DATA_STRING_ERROR
;
710 return VFR_RETURN_SUCCESS
;
714 CVfrVarDataTypeDB::GetTypeField (
715 IN CONST CHAR8
*FName
,
716 IN SVfrDataType
*Type
,
717 OUT SVfrDataField
*&Field
720 SVfrDataField
*pField
= NULL
;
722 if ((FName
== NULL
) || (Type
== NULL
)) {
723 return VFR_RETURN_FATAL_ERROR
;
726 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
728 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
729 // add code to adjust it.
731 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
732 if (strcmp (FName
, "Hour") == 0) {
734 } else if (strcmp (FName
, "Minute") == 0) {
736 } else if (strcmp (FName
, "Second") == 0) {
741 if (strcmp (pField
->mFieldName
, FName
) == 0) {
743 return VFR_RETURN_SUCCESS
;
747 return VFR_RETURN_UNDEFINED
;
751 CVfrVarDataTypeDB::GetFieldOffset (
752 IN SVfrDataField
*Field
,
755 IN BOOLEAN IsBitField
759 return VFR_RETURN_FATAL_ERROR
;
763 // Framework Vfr file Array Index is from 1.
764 // But Uefi Vfr file Array Index is from 0.
766 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
768 return VFR_RETURN_ERROR_ARRARY_NUM
;
770 ArrayIdx
= ArrayIdx
- 1;
773 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
774 return VFR_RETURN_ERROR_ARRARY_NUM
;
778 // Be compatible with the current usage
779 // If ArraryIdx is not specified, the first one is used.
781 // if ArrayNum is larger than zero, ArraryIdx must be specified.
783 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
784 // return VFR_RETURN_ERROR_ARRARY_NUM;
788 Offset
= Field
->mBitOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
) * 8;
790 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
792 return VFR_RETURN_SUCCESS
;
796 CVfrVarDataTypeDB::GetFieldWidth (
797 IN SVfrDataField
*Field
804 return Field
->mFieldType
->mType
;
808 CVfrVarDataTypeDB::GetFieldSize (
809 IN SVfrDataField
*Field
,
815 return VFR_RETURN_FATAL_ERROR
;
818 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
819 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
822 return Field
->mBitWidth
;
824 return Field
->mFieldType
->mTotalSize
;
830 CVfrVarDataTypeDB::InternalTypesListInit (
834 SVfrDataType
*New
= NULL
;
837 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
838 New
= new SVfrDataType
;
840 assert (strlen (gInternalTypesTable
[Index
].mTypeName
) < MAX_NAME_LEN
);
841 strncpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
, MAX_NAME_LEN
- 1);
842 New
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
843 New
->mType
= gInternalTypesTable
[Index
].mType
;
844 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
845 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
846 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
847 SVfrDataField
*pYearField
= new SVfrDataField
;
848 SVfrDataField
*pMonthField
= new SVfrDataField
;
849 SVfrDataField
*pDayField
= new SVfrDataField
;
851 strcpy (pYearField
->mFieldName
, "Year");
852 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
853 pYearField
->mOffset
= 0;
854 pYearField
->mNext
= pMonthField
;
855 pYearField
->mArrayNum
= 0;
856 pYearField
->mIsBitField
= FALSE
;
858 strcpy (pMonthField
->mFieldName
, "Month");
859 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
860 pMonthField
->mOffset
= 2;
861 pMonthField
->mNext
= pDayField
;
862 pMonthField
->mArrayNum
= 0;
863 pMonthField
->mIsBitField
= FALSE
;
865 strcpy (pDayField
->mFieldName
, "Day");
866 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
867 pDayField
->mOffset
= 3;
868 pDayField
->mNext
= NULL
;
869 pDayField
->mArrayNum
= 0;
870 pDayField
->mIsBitField
= FALSE
;
872 New
->mMembers
= pYearField
;
873 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
874 SVfrDataField
*pHoursField
= new SVfrDataField
;
875 SVfrDataField
*pMinutesField
= new SVfrDataField
;
876 SVfrDataField
*pSecondsField
= new SVfrDataField
;
878 strcpy (pHoursField
->mFieldName
, "Hours");
879 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
880 pHoursField
->mOffset
= 0;
881 pHoursField
->mNext
= pMinutesField
;
882 pHoursField
->mArrayNum
= 0;
883 pHoursField
->mIsBitField
= FALSE
;
885 strcpy (pMinutesField
->mFieldName
, "Minutes");
886 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
887 pMinutesField
->mOffset
= 1;
888 pMinutesField
->mNext
= pSecondsField
;
889 pMinutesField
->mArrayNum
= 0;
890 pMinutesField
->mIsBitField
= FALSE
;
892 strcpy (pSecondsField
->mFieldName
, "Seconds");
893 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
894 pSecondsField
->mOffset
= 2;
895 pSecondsField
->mNext
= NULL
;
896 pSecondsField
->mArrayNum
= 0;
897 pSecondsField
->mIsBitField
= FALSE
;
899 New
->mMembers
= pHoursField
;
900 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
901 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
902 SVfrDataField
*pFormIdField
= new SVfrDataField
;
903 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
904 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
906 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
907 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
908 pQuestionIdField
->mOffset
= 0;
909 pQuestionIdField
->mNext
= pFormIdField
;
910 pQuestionIdField
->mArrayNum
= 0;
911 pQuestionIdField
->mIsBitField
= FALSE
;
913 strcpy (pFormIdField
->mFieldName
, "FormId");
914 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
915 pFormIdField
->mOffset
= 2;
916 pFormIdField
->mNext
= pFormSetGuidField
;
917 pFormIdField
->mArrayNum
= 0;
918 pFormIdField
->mIsBitField
= FALSE
;
920 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
921 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
922 pFormSetGuidField
->mOffset
= 4;
923 pFormSetGuidField
->mNext
= pDevicePathField
;
924 pFormSetGuidField
->mArrayNum
= 0;
925 pFormSetGuidField
->mIsBitField
= FALSE
;
927 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
928 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
929 pDevicePathField
->mOffset
= 20;
930 pDevicePathField
->mNext
= NULL
;
931 pDevicePathField
->mArrayNum
= 0;
932 pDevicePathField
->mIsBitField
= FALSE
;
934 New
->mMembers
= pQuestionIdField
;
936 New
->mMembers
= NULL
;
939 RegisterNewType (New
);
945 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
949 mDataTypeList
= NULL
;
951 mCurrDataField
= NULL
;
952 mPackAlign
= DEFAULT_PACK_ALIGN
;
954 mFirstNewDataTypeName
= NULL
;
955 mCurrDataType
= NULL
;
957 InternalTypesListInit ();
960 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
965 SVfrDataField
*pField
;
966 SVfrPackStackNode
*pPack
;
968 if (mNewDataType
!= NULL
) {
972 while (mDataTypeList
!= NULL
) {
973 pType
= mDataTypeList
;
974 mDataTypeList
= mDataTypeList
->mNext
;
975 while(pType
->mMembers
!= NULL
) {
976 pField
= pType
->mMembers
;
977 pType
->mMembers
= pType
->mMembers
->mNext
;
983 while (mPackStack
!= NULL
) {
985 mPackStack
= mPackStack
->mNext
;
991 CVfrVarDataTypeDB::Pack (
994 IN CHAR8
*Identifier
,
999 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
1001 if (Action
& VFR_PACK_SHOW
) {
1002 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
1003 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
1006 if (Action
& VFR_PACK_PUSH
) {
1007 SVfrPackStackNode
*pNew
= NULL
;
1009 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
1010 return VFR_RETURN_FATAL_ERROR
;
1012 pNew
->mNext
= mPackStack
;
1016 if (Action
& VFR_PACK_POP
) {
1017 SVfrPackStackNode
*pNode
= NULL
;
1019 if (mPackStack
== NULL
) {
1020 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
1023 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1024 if (pNode
->Match (Identifier
) == TRUE
) {
1025 mPackAlign
= pNode
->mNumber
;
1026 mPackStack
= pNode
->mNext
;
1031 if (Action
& VFR_PACK_ASSIGN
) {
1032 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
1033 if ((PackAlign
== 0) || (PackAlign
> 16)) {
1034 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
1036 mPackAlign
= PackAlign
;
1040 return VFR_RETURN_SUCCESS
;
1044 CVfrVarDataTypeDB::DeclareDataTypeBegin (
1048 SVfrDataType
*pNewType
= NULL
;
1050 pNewType
= new SVfrDataType
;
1051 pNewType
->mTypeName
[0] = '\0';
1052 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
1053 pNewType
->mAlign
= DEFAULT_ALIGN
;
1054 pNewType
->mTotalSize
= 0;
1055 pNewType
->mMembers
= NULL
;
1056 pNewType
->mNext
= NULL
;
1057 pNewType
->mHasBitField
= FALSE
;
1059 mNewDataType
= pNewType
;
1063 CVfrVarDataTypeDB::SetNewTypeName (
1067 SVfrDataType
*pType
;
1069 if (mNewDataType
== NULL
) {
1070 return VFR_RETURN_ERROR_SKIPED
;
1072 if (TypeName
== NULL
) {
1073 return VFR_RETURN_FATAL_ERROR
;
1075 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
1076 return VFR_RETURN_INVALID_PARAMETER
;
1079 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1080 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1081 return VFR_RETURN_REDEFINED
;
1085 strncpy(mNewDataType
->mTypeName
, TypeName
, MAX_NAME_LEN
- 1);
1086 mNewDataType
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
1087 return VFR_RETURN_SUCCESS
;
1091 Record the bit field info in the data type.
1093 @param FieldName Point to the field name.
1094 @param TypeName Point to the type name.
1095 @param Width The bit width.
1096 @param FieldInUnion The filed is in Union type or Structure type.
1100 CVfrVarDataTypeDB::DataTypeAddBitField (
1101 IN CHAR8
*FieldName
,
1104 IN BOOLEAN FieldInUnion
1107 SVfrDataField
*pNewField
= NULL
;
1108 SVfrDataType
*pFieldType
= NULL
;
1109 SVfrDataField
*pTmp
;
1111 UINT32 MaxDataTypeSize
;
1112 BOOLEAN UpdateTotalSize
;
1114 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1116 if (Width
> MAX_BIT_WIDTH
) {
1117 return VFR_RETURN_BIT_WIDTH_ERROR
;
1120 if (Width
> pFieldType
->mTotalSize
* 8) {
1121 return VFR_RETURN_BIT_WIDTH_ERROR
;
1124 if (FieldName
!= NULL
&& strlen (FieldName
) >= MAX_NAME_LEN
) {
1125 return VFR_RETURN_INVALID_PARAMETER
;
1128 if (Width
== 0 && FieldName
!= NULL
) {
1129 return VFR_RETURN_INVALID_PARAMETER
;
1132 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1133 if (FieldName
!= NULL
&& strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1134 return VFR_RETURN_REDEFINED
;
1138 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1139 UpdateTotalSize
= FALSE
;
1141 if ((pNewField
= new SVfrDataField
) == NULL
) {
1142 return VFR_RETURN_OUT_FOR_RESOURCES
;
1145 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1146 if (FieldName
!= NULL
) {
1147 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1148 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1150 pNewField
->mFieldType
= pFieldType
;
1151 pNewField
->mIsBitField
= TRUE
;
1152 pNewField
->mBitWidth
= Width
;
1153 pNewField
->mArrayNum
= 0;
1154 pNewField
->mBitOffset
= 0;
1155 pNewField
->mOffset
= 0;
1157 if (mNewDataType
->mMembers
== NULL
) {
1158 mNewDataType
->mMembers
= pNewField
;
1159 pNewField
->mNext
= NULL
;
1161 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1163 pTmp
->mNext
= pNewField
;
1164 pNewField
->mNext
= NULL
;
1168 pNewField
->mOffset
= 0;
1169 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1170 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1174 // Check whether the bit fields can be contained within one FieldType.
1176 if (pTmp
!= NULL
&& pTmp
->mIsBitField
&& strcmp (pTmp
->mFieldType
->mTypeName
, pNewField
->mFieldType
->mTypeName
) == 0 &&
1177 (pTmp
->mBitOffset
- pTmp
->mOffset
* 8) + pTmp
->mBitWidth
+ pNewField
->mBitWidth
<= pNewField
->mFieldType
->mTotalSize
* 8) {
1178 pNewField
->mBitOffset
= pTmp
->mBitOffset
+ pTmp
->mBitWidth
;
1179 pNewField
->mOffset
= pTmp
->mOffset
;
1181 // If BitWidth=0,used to force alignment at the next word boundary.
1182 // So make this bit field occupy the remaing bit width of current field type.
1184 if (pNewField
->mBitWidth
== 0) {
1185 pNewField
->mBitWidth
= pNewField
->mFieldType
->mTotalSize
* 8 - (pNewField
->mBitOffset
- pTmp
->mOffset
* 8);
1189 // The bit filed start a new memory
1191 pNewField
->mBitOffset
= mNewDataType
->mTotalSize
* 8;
1192 UpdateTotalSize
= TRUE
;
1196 if (UpdateTotalSize
){
1197 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1198 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1200 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1202 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
);
1205 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1206 mNewDataType
->mHasBitField
= TRUE
;
1207 return VFR_RETURN_SUCCESS
;
1211 CVfrVarDataTypeDB::DataTypeAddField (
1212 IN CHAR8
*FieldName
,
1215 IN BOOLEAN FieldInUnion
1218 SVfrDataField
*pNewField
= NULL
;
1219 SVfrDataType
*pFieldType
= NULL
;
1220 SVfrDataField
*pTmp
;
1222 UINT32 MaxDataTypeSize
;
1224 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1225 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1227 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1228 return VFR_RETURN_INVALID_PARAMETER
;
1231 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1232 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1233 return VFR_RETURN_REDEFINED
;
1237 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1239 if ((pNewField
= new SVfrDataField
) == NULL
) {
1240 return VFR_RETURN_OUT_FOR_RESOURCES
;
1242 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1243 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1244 pNewField
->mFieldType
= pFieldType
;
1245 pNewField
->mArrayNum
= ArrayNum
;
1246 pNewField
->mIsBitField
= FALSE
;
1247 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1248 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1250 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1252 if (mNewDataType
->mMembers
== NULL
) {
1253 mNewDataType
->mMembers
= pNewField
;
1254 pNewField
->mNext
= NULL
;
1256 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1258 pTmp
->mNext
= pNewField
;
1259 pNewField
->mNext
= NULL
;
1262 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1265 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1266 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1268 pNewField
->mOffset
= 0;
1270 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1273 return VFR_RETURN_SUCCESS
;
1277 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1281 if (mNewDataType
->mTypeName
[0] == '\0') {
1285 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1286 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1289 RegisterNewType (mNewDataType
);
1290 if (mFirstNewDataTypeName
== NULL
) {
1291 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1294 mNewDataType
= NULL
;
1298 CVfrVarDataTypeDB::GetDataType (
1300 OUT SVfrDataType
**DataType
1303 SVfrDataType
*pDataType
= NULL
;
1305 if (TypeName
== NULL
) {
1306 return VFR_RETURN_ERROR_SKIPED
;
1309 if (DataType
== NULL
) {
1310 return VFR_RETURN_FATAL_ERROR
;
1315 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1316 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1317 *DataType
= pDataType
;
1318 return VFR_RETURN_SUCCESS
;
1322 return VFR_RETURN_UNDEFINED
;
1326 CVfrVarDataTypeDB::GetDataTypeSize (
1331 SVfrDataType
*pDataType
= NULL
;
1334 return VFR_RETURN_FATAL_ERROR
;
1338 DataType
= DataType
& 0x0F;
1341 // For user defined data type, the size can't be got by this function.
1343 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1344 return VFR_RETURN_SUCCESS
;
1347 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1348 if (DataType
== pDataType
->mType
) {
1349 *Size
= pDataType
->mTotalSize
;
1350 return VFR_RETURN_SUCCESS
;
1354 return VFR_RETURN_UNDEFINED
;
1358 CVfrVarDataTypeDB::GetDataTypeSize (
1363 SVfrDataType
*pDataType
= NULL
;
1366 return VFR_RETURN_FATAL_ERROR
;
1371 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1372 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1373 *Size
= pDataType
->mTotalSize
;
1374 return VFR_RETURN_SUCCESS
;
1378 return VFR_RETURN_UNDEFINED
;
1382 CVfrVarDataTypeDB::GetDataFieldInfo (
1387 OUT BOOLEAN
&BitField
1390 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1391 UINT32 ArrayIdx
, Tmp
;
1392 SVfrDataType
*pType
= NULL
;
1393 SVfrDataField
*pField
= NULL
;
1397 Type
= EFI_IFR_TYPE_OTHER
;
1399 VarStrName
= VarStr
;
1401 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1402 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1404 BitField
= IsThisBitField (VarStrName
);
1407 // if it is not struct data type
1409 Type
= pType
->mType
;
1410 Size
= pType
->mTotalSize
;
1412 while (*VarStr
!= '\0') {
1413 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1414 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1415 pType
= pField
->mFieldType
;
1416 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
, pField
->mIsBitField
), VFR_RETURN_SUCCESS
);
1417 if (BitField
&& !pField
->mIsBitField
) {
1418 Offset
= (UINT16
) (Offset
+ Tmp
* 8);
1420 Offset
= (UINT16
) (Offset
+ Tmp
);
1422 Type
= GetFieldWidth (pField
);
1423 Size
= GetFieldSize (pField
, ArrayIdx
, BitField
);
1425 return VFR_RETURN_SUCCESS
;
1429 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1430 OUT CHAR8
***NameList
,
1431 OUT UINT32
*ListSize
1435 SVfrDataType
*pType
;
1437 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1438 return VFR_RETURN_FATAL_ERROR
;
1444 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1445 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1450 if (*ListSize
== 0) {
1451 return VFR_RETURN_SUCCESS
;
1454 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1456 return VFR_RETURN_OUT_FOR_RESOURCES
;
1459 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1460 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1461 (*NameList
)[Index
] = pType
->mTypeName
;
1464 return VFR_RETURN_SUCCESS
;
1468 CVfrVarDataTypeDB::IsTypeNameDefined (
1472 SVfrDataType
*pType
;
1474 if (TypeName
== NULL
) {
1478 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1479 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1488 CVfrVarDataTypeDB::Dump (
1492 SVfrDataType
*pTNode
;
1493 SVfrDataField
*pFNode
;
1495 fprintf (File
, "\n\n***************************************************************\n");
1496 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1497 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1498 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1499 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1500 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1501 if (pFNode
->mArrayNum
> 0) {
1502 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1503 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1505 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1506 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1509 fprintf (File
, "\t\t};\n");
1510 fprintf (File
, "---------------------------------------------------------------\n");
1512 fprintf (File
, "***************************************************************\n");
1515 #ifdef CVFR_VARDATATYPEDB_DEBUG
1517 CVfrVarDataTypeDB::ParserDB (
1521 SVfrDataType
*pTNode
;
1522 SVfrDataField
*pFNode
;
1524 printf ("***************************************************************\n");
1525 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1526 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1527 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1528 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1529 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1530 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1532 printf ("\t\t};\n");
1533 printf ("---------------------------------------------------------------\n");
1535 printf ("***************************************************************\n");
1539 SVfrVarStorageNode::SVfrVarStorageNode (
1541 IN CHAR8
*StoreName
,
1542 IN EFI_VARSTORE_ID VarStoreId
,
1543 IN EFI_STRING_ID VarName
,
1551 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1553 if (StoreName
!= NULL
) {
1554 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1555 strcpy (mVarStoreName
, StoreName
);
1557 mVarStoreName
= NULL
;
1560 mVarStoreId
= VarStoreId
;
1561 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1562 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1563 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1564 mAssignedFlag
= Flag
;
1567 SVfrVarStorageNode::SVfrVarStorageNode (
1569 IN CHAR8
*StoreName
,
1570 IN EFI_VARSTORE_ID VarStoreId
,
1571 IN SVfrDataType
*DataType
,
1572 IN BOOLEAN BitsVarstore
,
1579 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1581 if (StoreName
!= NULL
) {
1582 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1583 strcpy (mVarStoreName
, StoreName
);
1585 mVarStoreName
= NULL
;
1588 mVarStoreId
= VarStoreId
;
1590 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER_BITS
;
1592 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1594 mStorageInfo
.mDataType
= DataType
;
1595 mAssignedFlag
= Flag
;
1598 SVfrVarStorageNode::SVfrVarStorageNode (
1599 IN CHAR8
*StoreName
,
1600 IN EFI_VARSTORE_ID VarStoreId
1603 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1604 if (StoreName
!= NULL
) {
1605 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1606 strcpy (mVarStoreName
, StoreName
);
1608 mVarStoreName
= NULL
;
1611 mVarStoreId
= VarStoreId
;
1612 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1613 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1614 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1615 mAssignedFlag
= FALSE
;
1618 SVfrVarStorageNode::~SVfrVarStorageNode (
1622 if (mVarStoreName
!= NULL
) {
1623 delete[] mVarStoreName
;
1626 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1627 delete[] mStorageInfo
.mNameSpace
.mNameTable
;
1631 CVfrDataStorage::CVfrDataStorage (
1637 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1638 mFreeVarStoreIdBitMap
[Index
] = 0;
1641 // Question ID 0 is reserved.
1642 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1644 mBufferVarStoreList
= NULL
;
1645 mEfiVarStoreList
= NULL
;
1646 mNameVarStoreList
= NULL
;
1647 mCurrVarStorageNode
= NULL
;
1648 mNewVarStorageNode
= NULL
;
1649 mBufferFieldInfoListHead
= NULL
;
1650 mBufferFieldInfoListTail
= NULL
;
1653 CVfrDataStorage::~CVfrDataStorage (
1657 SVfrVarStorageNode
*pNode
;
1659 while (mBufferVarStoreList
!= NULL
) {
1660 pNode
= mBufferVarStoreList
;
1661 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1664 while (mEfiVarStoreList
!= NULL
) {
1665 pNode
= mEfiVarStoreList
;
1666 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1669 while (mNameVarStoreList
!= NULL
) {
1670 pNode
= mNameVarStoreList
;
1671 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1674 if (mNewVarStorageNode
!= NULL
) {
1675 delete mNewVarStorageNode
;
1680 CVfrDataStorage::GetFreeVarStoreId (
1681 EFI_VFR_VARSTORE_TYPE VarType
1684 UINT32 Index
, Mask
, Offset
;
1687 // Assign the different ID range for the different type VarStore to support Framework Vfr
1690 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1692 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1694 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1698 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1699 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1704 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1705 return EFI_VARSTORE_ID_INVALID
;
1708 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1709 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1710 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1711 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1715 return EFI_VARSTORE_ID_INVALID
;
1719 CVfrDataStorage::ChekVarStoreIdFree (
1720 IN EFI_VARSTORE_ID VarStoreId
1723 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1724 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1726 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1730 CVfrDataStorage::MarkVarStoreIdUsed (
1731 IN EFI_VARSTORE_ID VarStoreId
1734 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1735 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1737 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1741 CVfrDataStorage::MarkVarStoreIdUnused (
1742 IN EFI_VARSTORE_ID VarStoreId
1745 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1746 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1748 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1752 CVfrDataStorage::DeclareNameVarStoreBegin (
1753 IN CHAR8
*StoreName
,
1754 IN EFI_VARSTORE_ID VarStoreId
1757 SVfrVarStorageNode
*pNode
= NULL
;
1758 EFI_VARSTORE_ID TmpVarStoreId
;
1760 if (StoreName
== NULL
) {
1761 return VFR_RETURN_FATAL_ERROR
;
1764 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1765 return VFR_RETURN_REDEFINED
;
1768 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1769 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1771 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1772 return VFR_RETURN_VARSTOREID_REDEFINED
;
1774 MarkVarStoreIdUsed (VarStoreId
);
1777 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1778 return VFR_RETURN_UNDEFINED
;
1781 mNewVarStorageNode
= pNode
;
1783 return VFR_RETURN_SUCCESS
;
1787 CVfrDataStorage::NameTableAddItem (
1788 IN EFI_STRING_ID Item
1791 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1794 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1795 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1797 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1798 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1799 return VFR_RETURN_OUT_FOR_RESOURCES
;
1801 memcpy (NewTable
, OldTable
, TableSize
);
1802 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1805 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1806 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1808 return VFR_RETURN_SUCCESS
;
1812 CVfrDataStorage::DeclareNameVarStoreEnd (
1816 mNewVarStorageNode
->mGuid
= *Guid
;
1817 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1818 mNameVarStoreList
= mNewVarStorageNode
;
1820 mNewVarStorageNode
= NULL
;
1822 return VFR_RETURN_SUCCESS
;
1826 CVfrDataStorage::DeclareEfiVarStore (
1827 IN CHAR8
*StoreName
,
1829 IN EFI_STRING_ID NameStrId
,
1834 SVfrVarStorageNode
*pNode
;
1835 EFI_VARSTORE_ID VarStoreId
;
1837 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1838 return VFR_RETURN_FATAL_ERROR
;
1841 if (VarSize
> sizeof (UINT64
)) {
1842 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1845 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1846 return VFR_RETURN_REDEFINED
;
1849 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1850 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1851 return VFR_RETURN_OUT_FOR_RESOURCES
;
1854 pNode
->mNext
= mEfiVarStoreList
;
1855 mEfiVarStoreList
= pNode
;
1857 return VFR_RETURN_SUCCESS
;
1861 CVfrDataStorage::DeclareBufferVarStore (
1862 IN CHAR8
*StoreName
,
1864 IN CVfrVarDataTypeDB
*DataTypeDB
,
1866 IN EFI_VARSTORE_ID VarStoreId
,
1867 IN BOOLEAN IsBitVarStore
,
1871 SVfrVarStorageNode
*pNew
= NULL
;
1872 SVfrDataType
*pDataType
= NULL
;
1873 EFI_VARSTORE_ID TempVarStoreId
;
1875 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1876 return VFR_RETURN_FATAL_ERROR
;
1879 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1880 return VFR_RETURN_REDEFINED
;
1883 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1885 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1886 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1888 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1889 return VFR_RETURN_VARSTOREID_REDEFINED
;
1891 MarkVarStoreIdUsed (VarStoreId
);
1894 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, IsBitVarStore
, Flag
)) == NULL
) {
1895 return VFR_RETURN_OUT_FOR_RESOURCES
;
1898 pNew
->mNext
= mBufferVarStoreList
;
1899 mBufferVarStoreList
= pNew
;
1901 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1902 return VFR_RETURN_FATAL_ERROR
;
1905 return VFR_RETURN_SUCCESS
;
1909 CVfrDataStorage::GetVarStoreByDataType (
1910 IN CHAR8
*DataTypeName
,
1911 OUT SVfrVarStorageNode
**VarNode
,
1912 IN EFI_GUID
*VarGuid
1915 SVfrVarStorageNode
*pNode
;
1916 SVfrVarStorageNode
*MatchNode
;
1919 // Framework VFR uses Data type name as varstore name, so don't need check again.
1921 if (VfrCompatibleMode
) {
1922 return VFR_RETURN_UNDEFINED
;
1926 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1927 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1931 if ((VarGuid
!= NULL
)) {
1932 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1934 return VFR_RETURN_SUCCESS
;
1937 if (MatchNode
== NULL
) {
1941 // More than one varstores referred the same data structures.
1943 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1948 if (MatchNode
== NULL
) {
1949 return VFR_RETURN_UNDEFINED
;
1952 *VarNode
= MatchNode
;
1953 return VFR_RETURN_SUCCESS
;
1957 CVfrDataStorage::CheckGuidField (
1958 IN SVfrVarStorageNode
*pNode
,
1959 IN EFI_GUID
*StoreGuid
,
1960 IN BOOLEAN
*HasFoundOne
,
1961 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1964 if (StoreGuid
!= NULL
) {
1966 // If has guid info, compare the guid filed.
1968 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1970 // Both name and guid are same, this this varstore.
1972 mCurrVarStorageNode
= pNode
;
1973 *ReturnCode
= VFR_RETURN_SUCCESS
;
1978 // Not has Guid field, check whether this name is the only one.
1982 // The name has conflict, return name redefined.
1984 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1988 *HasFoundOne
= TRUE
;
1989 mCurrVarStorageNode
= pNode
;
1996 Base on the input store name and guid to find the varstore id.
1998 If both name and guid are inputed, base on the name and guid to
1999 found the varstore. If only name inputed, base on the name to
2000 found the varstore and go on to check whether more than one varstore
2001 has the same name. If only has found one varstore, return this
2002 varstore; if more than one varstore has same name, return varstore
2003 name redefined error. If no varstore found by varstore name, call
2004 function GetVarStoreByDataType and use inputed varstore name as
2005 data type name to search.
2008 CVfrDataStorage::GetVarStoreId (
2009 IN CHAR8
*StoreName
,
2010 OUT EFI_VARSTORE_ID
*VarStoreId
,
2011 IN EFI_GUID
*StoreGuid
2014 EFI_VFR_RETURN_CODE ReturnCode
;
2015 SVfrVarStorageNode
*pNode
;
2016 BOOLEAN HasFoundOne
= FALSE
;
2018 mCurrVarStorageNode
= NULL
;
2020 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2021 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2022 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2023 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2029 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2030 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2031 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2032 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2038 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2039 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2040 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2041 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2048 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2049 return VFR_RETURN_SUCCESS
;
2052 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
2055 // Assume that Data structure name is used as StoreName, and check again.
2057 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
2058 if (pNode
!= NULL
) {
2059 mCurrVarStorageNode
= pNode
;
2060 *VarStoreId
= pNode
->mVarStoreId
;
2067 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2068 IN EFI_VARSTORE_ID VarStoreId
,
2069 OUT CHAR8
**DataTypeName
2072 SVfrVarStorageNode
*pNode
;
2074 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2075 return VFR_RETURN_FATAL_ERROR
;
2078 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2079 if (pNode
->mVarStoreId
== VarStoreId
) {
2080 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
2081 return VFR_RETURN_SUCCESS
;
2085 return VFR_RETURN_UNDEFINED
;
2088 EFI_VFR_VARSTORE_TYPE
2089 CVfrDataStorage::GetVarStoreType (
2090 IN EFI_VARSTORE_ID VarStoreId
2093 SVfrVarStorageNode
*pNode
;
2094 EFI_VFR_VARSTORE_TYPE VarStoreType
;
2096 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
2098 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2099 return VarStoreType
;
2102 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2103 if (pNode
->mVarStoreId
== VarStoreId
) {
2104 VarStoreType
= pNode
->mVarStoreType
;
2105 return VarStoreType
;
2109 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2110 if (pNode
->mVarStoreId
== VarStoreId
) {
2111 VarStoreType
= pNode
->mVarStoreType
;
2112 return VarStoreType
;
2116 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2117 if (pNode
->mVarStoreId
== VarStoreId
) {
2118 VarStoreType
= pNode
->mVarStoreType
;
2119 return VarStoreType
;
2123 return VarStoreType
;
2127 CVfrDataStorage::GetVarStoreGuid (
2128 IN EFI_VARSTORE_ID VarStoreId
2131 SVfrVarStorageNode
*pNode
;
2136 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2140 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2141 if (pNode
->mVarStoreId
== VarStoreId
) {
2142 VarGuid
= &pNode
->mGuid
;
2147 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2148 if (pNode
->mVarStoreId
== VarStoreId
) {
2149 VarGuid
= &pNode
->mGuid
;
2154 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2155 if (pNode
->mVarStoreId
== VarStoreId
) {
2156 VarGuid
= &pNode
->mGuid
;
2165 CVfrDataStorage::GetVarStoreName (
2166 IN EFI_VARSTORE_ID VarStoreId
,
2167 OUT CHAR8
**VarStoreName
2170 SVfrVarStorageNode
*pNode
;
2172 if (VarStoreName
== NULL
) {
2173 return VFR_RETURN_FATAL_ERROR
;
2176 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2177 if (pNode
->mVarStoreId
== VarStoreId
) {
2178 *VarStoreName
= pNode
->mVarStoreName
;
2179 return VFR_RETURN_SUCCESS
;
2183 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2184 if (pNode
->mVarStoreId
== VarStoreId
) {
2185 *VarStoreName
= pNode
->mVarStoreName
;
2186 return VFR_RETURN_SUCCESS
;
2190 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2191 if (pNode
->mVarStoreId
== VarStoreId
) {
2192 *VarStoreName
= pNode
->mVarStoreName
;
2193 return VFR_RETURN_SUCCESS
;
2197 *VarStoreName
= NULL
;
2198 return VFR_RETURN_UNDEFINED
;
2202 CVfrDataStorage::GetEfiVarStoreInfo (
2203 IN OUT EFI_VARSTORE_INFO
*Info
2207 return VFR_RETURN_FATAL_ERROR
;
2210 if (mCurrVarStorageNode
== NULL
) {
2211 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
2214 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
2215 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
2216 switch (Info
->mVarTotalSize
) {
2218 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
2221 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
2224 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
2227 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2230 return VFR_RETURN_FATAL_ERROR
;
2233 return VFR_RETURN_SUCCESS
;
2237 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2238 IN EFI_VARSTORE_INFO
*Info
2241 BufferVarStoreFieldInfoNode
*pNew
;
2243 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2244 return VFR_RETURN_FATAL_ERROR
;
2247 if (mBufferFieldInfoListHead
== NULL
) {
2248 mBufferFieldInfoListHead
= pNew
;
2249 mBufferFieldInfoListTail
= pNew
;
2251 mBufferFieldInfoListTail
->mNext
= pNew
;
2252 mBufferFieldInfoListTail
= pNew
;
2255 return VFR_RETURN_SUCCESS
;
2259 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2260 IN OUT EFI_VARSTORE_INFO
*Info
2263 BufferVarStoreFieldInfoNode
*pNode
;
2265 pNode
= mBufferFieldInfoListHead
;
2266 while (pNode
!= NULL
) {
2267 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2268 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2269 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2270 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2271 return VFR_RETURN_SUCCESS
;
2273 pNode
= pNode
->mNext
;
2275 return VFR_RETURN_FATAL_ERROR
;
2279 CVfrDataStorage::GetNameVarStoreInfo (
2280 OUT EFI_VARSTORE_INFO
*Info
,
2285 return VFR_RETURN_FATAL_ERROR
;
2288 if (mCurrVarStorageNode
== NULL
) {
2289 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2293 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2295 if (VfrCompatibleMode
) {
2297 return VFR_RETURN_ERROR_ARRARY_NUM
;
2302 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2304 return VFR_RETURN_SUCCESS
;
2307 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2308 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2310 IN EFI_STRING_ID DefaultStoreNameId
,
2314 mObjBinAddr
= ObjBinAddr
;
2316 if (RefName
!= NULL
) {
2317 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2318 strcpy (mRefName
, RefName
);
2324 mDefaultId
= DefaultId
;
2325 mDefaultStoreNameId
= DefaultStoreNameId
;
2328 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2332 if (mRefName
!= NULL
) {
2337 CVfrDefaultStore::CVfrDefaultStore (
2341 mDefaultStoreList
= NULL
;
2344 CVfrDefaultStore::~CVfrDefaultStore (
2348 SVfrDefaultStoreNode
*pTmp
= NULL
;
2350 while (mDefaultStoreList
!= NULL
) {
2351 pTmp
= mDefaultStoreList
;
2352 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2358 CVfrDefaultStore::RegisterDefaultStore (
2359 IN CHAR8
*ObjBinAddr
,
2361 IN EFI_STRING_ID DefaultStoreNameId
,
2365 SVfrDefaultStoreNode
*pNode
= NULL
;
2367 if (RefName
== NULL
) {
2368 return VFR_RETURN_FATAL_ERROR
;
2371 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2372 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2373 return VFR_RETURN_REDEFINED
;
2377 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2378 return VFR_RETURN_OUT_FOR_RESOURCES
;
2381 pNode
->mNext
= mDefaultStoreList
;
2382 mDefaultStoreList
= pNode
;
2384 return VFR_RETURN_SUCCESS
;
2388 * assign new reference name or new default store name id only if
2389 * the original is invalid
2392 CVfrDefaultStore::ReRegisterDefaultStoreById (
2393 IN UINT16 DefaultId
,
2395 IN EFI_STRING_ID DefaultStoreNameId
2398 SVfrDefaultStoreNode
*pNode
= NULL
;
2400 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2401 if (pNode
->mDefaultId
== DefaultId
) {
2406 if (pNode
== NULL
) {
2407 return VFR_RETURN_UNDEFINED
;
2409 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2410 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2411 if (pNode
->mObjBinAddr
!= NULL
) {
2412 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2415 return VFR_RETURN_REDEFINED
;
2418 if (RefName
!= NULL
) {
2419 delete pNode
->mRefName
;
2420 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2421 if (pNode
->mRefName
!= NULL
) {
2422 strcpy (pNode
->mRefName
, RefName
);
2427 return VFR_RETURN_SUCCESS
;
2431 CVfrDefaultStore::DefaultIdRegistered (
2435 SVfrDefaultStoreNode
*pNode
= NULL
;
2437 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2438 if (pNode
->mDefaultId
== DefaultId
) {
2447 CVfrDefaultStore::GetDefaultId (
2449 OUT UINT16
*DefaultId
2452 SVfrDefaultStoreNode
*pTmp
= NULL
;
2454 if (DefaultId
== NULL
) {
2455 return VFR_RETURN_FATAL_ERROR
;
2458 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2459 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2460 *DefaultId
= pTmp
->mDefaultId
;
2461 return VFR_RETURN_SUCCESS
;
2465 return VFR_RETURN_UNDEFINED
;
2469 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2470 IN EFI_VARSTORE_ID DefaultId
,
2471 IN EFI_VARSTORE_INFO
&Info
,
2472 IN CHAR8
*VarStoreName
,
2473 IN EFI_GUID
*VarStoreGuid
,
2475 IN EFI_IFR_TYPE_VALUE Value
2478 SVfrDefaultStoreNode
*pNode
= NULL
;
2479 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2480 INTN Returnvalue
= 0;
2482 if (VarStoreName
== NULL
) {
2483 return VFR_RETURN_FATAL_ERROR
;
2486 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2487 if (pNode
->mDefaultId
== DefaultId
) {
2492 if (pNode
== NULL
) {
2493 return VFR_RETURN_UNDEFINED
;
2496 gCVfrBufferConfig
.Open ();
2498 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2499 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2500 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2505 gCVfrBufferConfig
.Close ();
2507 return VFR_RETURN_SUCCESS
;
2510 gCVfrBufferConfig
.Close ();
2511 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2514 SVfrRuleNode::SVfrRuleNode (
2519 if (RuleName
!= NULL
) {
2520 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2521 strcpy (mRuleName
, RuleName
);
2530 SVfrRuleNode::~SVfrRuleNode (
2534 if (mRuleName
!= NULL
) {
2539 CVfrRulesDB::CVfrRulesDB ()
2542 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2545 CVfrRulesDB::~CVfrRulesDB ()
2547 SVfrRuleNode
*pNode
;
2549 while(mRuleList
!= NULL
) {
2551 mRuleList
= mRuleList
->mNext
;
2557 CVfrRulesDB::RegisterRule (
2563 if (RuleName
== NULL
) {
2567 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2573 pNew
->mNext
= mRuleList
;
2578 CVfrRulesDB::GetRuleId (
2582 SVfrRuleNode
*pNode
;
2584 if (RuleName
== NULL
) {
2585 return EFI_RULE_ID_INVALID
;
2588 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2589 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2590 return pNode
->mRuleId
;
2594 return EFI_RULE_ID_INVALID
;
2597 CVfrRulesDB gCVfrRulesDB
;
2599 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2603 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2604 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2605 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2606 mVarType
= EFI_IFR_TYPE_OTHER
;
2611 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2612 IN EFI_VARSTORE_INFO
&Info
2615 mVarStoreId
= Info
.mVarStoreId
;
2616 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2617 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2618 mVarType
= Info
.mVarType
;
2619 mVarTotalSize
= Info
.mVarTotalSize
;
2620 mIsBitVar
= Info
.mIsBitVar
;
2624 EFI_VARSTORE_INFO::operator= (
2625 IN CONST EFI_VARSTORE_INFO
&Info
2628 if (this != &Info
) {
2629 mVarStoreId
= Info
.mVarStoreId
;
2630 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2631 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2632 mVarType
= Info
.mVarType
;
2633 mVarTotalSize
= Info
.mVarTotalSize
;
2634 mIsBitVar
= Info
.mIsBitVar
;
2641 EFI_VARSTORE_INFO::operator == (
2642 IN EFI_VARSTORE_INFO
*Info
2645 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2646 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2647 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2648 (mVarType
== Info
->mVarType
) &&
2649 (mVarTotalSize
== Info
->mVarTotalSize
) &&
2650 (mIsBitVar
== Info
->mIsBitVar
)) {
2657 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2658 IN EFI_VARSTORE_INFO
*Info
2661 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2662 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2663 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2664 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2668 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2670 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2671 mVarStoreInfo
.mVarTotalSize
= 0;
2672 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2673 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2677 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2680 CVfrQuestionDB::GetFreeQuestionId (
2684 UINT32 Index
, Mask
, Offset
;
2686 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2687 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2692 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2693 return EFI_QUESTION_ID_INVALID
;
2696 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2697 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2698 mFreeQIdBitMap
[Index
] |= Mask
;
2699 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2703 return EFI_QUESTION_ID_INVALID
;
2707 CVfrQuestionDB::ChekQuestionIdFree (
2708 IN EFI_QUESTION_ID QId
2711 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2712 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2714 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2718 CVfrQuestionDB::MarkQuestionIdUsed (
2719 IN EFI_QUESTION_ID QId
2722 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2723 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2725 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2729 CVfrQuestionDB::MarkQuestionIdUnused (
2730 IN EFI_QUESTION_ID QId
2733 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2734 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2736 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2739 SVfrQuestionNode::SVfrQuestionNode (
2747 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2750 mQtype
= QUESTION_NORMAL
;
2753 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2754 strcpy (mName
, "$DEFAULT");
2756 mName
= new CHAR8
[strlen (Name
) + 1];
2757 strcpy (mName
, Name
);
2760 if (VarIdStr
!= NULL
) {
2761 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2762 strcpy (mVarIdStr
, VarIdStr
);
2764 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2765 strcpy (mVarIdStr
, "$");
2769 SVfrQuestionNode::~SVfrQuestionNode (
2773 if (mName
!= NULL
) {
2777 if (mVarIdStr
!= NULL
) {
2782 CVfrQuestionDB::CVfrQuestionDB ()
2786 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2787 mFreeQIdBitMap
[Index
] = 0;
2790 // Question ID 0 is reserved.
2791 mFreeQIdBitMap
[0] = 0x80000000;
2792 mQuestionList
= NULL
;
2795 CVfrQuestionDB::~CVfrQuestionDB ()
2797 SVfrQuestionNode
*pNode
;
2799 while (mQuestionList
!= NULL
) {
2800 pNode
= mQuestionList
;
2801 mQuestionList
= mQuestionList
->mNext
;
2807 // Reset to init state
2810 CVfrQuestionDB::ResetInit(
2815 SVfrQuestionNode
*pNode
;
2817 while (mQuestionList
!= NULL
) {
2818 pNode
= mQuestionList
;
2819 mQuestionList
= mQuestionList
->mNext
;
2823 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2824 mFreeQIdBitMap
[Index
] = 0;
2827 // Question ID 0 is reserved.
2828 mFreeQIdBitMap
[0] = 0x80000000;
2829 mQuestionList
= NULL
;
2833 CVfrQuestionDB::PrintAllQuestion (
2837 SVfrQuestionNode
*pNode
= NULL
;
2839 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2840 printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2845 CVfrQuestionDB::RegisterQuestion (
2848 IN OUT EFI_QUESTION_ID
&QuestionId
2851 SVfrQuestionNode
*pNode
= NULL
;
2853 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2854 return VFR_RETURN_REDEFINED
;
2857 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2858 return VFR_RETURN_OUT_FOR_RESOURCES
;
2861 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2862 QuestionId
= GetFreeQuestionId ();
2865 // For Framework Vfr, don't check question ID conflict.
2867 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2869 return VFR_RETURN_QUESTIONID_REDEFINED
;
2871 MarkQuestionIdUsed (QuestionId
);
2873 pNode
->mQuestionId
= QuestionId
;
2875 pNode
->mNext
= mQuestionList
;
2876 mQuestionList
= pNode
;
2878 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2880 return VFR_RETURN_SUCCESS
;
2884 CVfrQuestionDB::RegisterOldDateQuestion (
2885 IN CHAR8
*YearVarId
,
2886 IN CHAR8
*MonthVarId
,
2888 IN OUT EFI_QUESTION_ID
&QuestionId
2891 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2894 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2898 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2901 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2904 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2908 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2909 QuestionId
= GetFreeQuestionId ();
2911 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2914 MarkQuestionIdUsed (QuestionId
);
2917 pNode
[0]->mQuestionId
= QuestionId
;
2918 pNode
[1]->mQuestionId
= QuestionId
;
2919 pNode
[2]->mQuestionId
= QuestionId
;
2920 pNode
[0]->mQtype
= QUESTION_DATE
;
2921 pNode
[1]->mQtype
= QUESTION_DATE
;
2922 pNode
[2]->mQtype
= QUESTION_DATE
;
2923 pNode
[0]->mNext
= pNode
[1];
2924 pNode
[1]->mNext
= pNode
[2];
2925 pNode
[2]->mNext
= mQuestionList
;
2926 mQuestionList
= pNode
[0];
2928 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2929 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2930 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2935 for (Index
= 0; Index
< 3; Index
++) {
2936 if (pNode
[Index
] != NULL
) {
2937 delete pNode
[Index
];
2940 QuestionId
= EFI_QUESTION_ID_INVALID
;
2944 CVfrQuestionDB::RegisterNewDateQuestion (
2946 IN CHAR8
*BaseVarId
,
2947 IN OUT EFI_QUESTION_ID
&QuestionId
2950 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2952 CHAR8
*VarIdStr
[3] = {NULL
, };
2955 if (BaseVarId
== NULL
&& Name
== NULL
) {
2956 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2957 QuestionId
= GetFreeQuestionId ();
2959 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2962 MarkQuestionIdUsed (QuestionId
);
2967 if (BaseVarId
!= NULL
) {
2968 Len
= strlen (BaseVarId
);
2970 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2971 if (VarIdStr
[0] != NULL
) {
2972 strcpy (VarIdStr
[0], BaseVarId
);
2973 strcat (VarIdStr
[0], ".Year");
2975 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2976 if (VarIdStr
[1] != NULL
) {
2977 strcpy (VarIdStr
[1], BaseVarId
);
2978 strcat (VarIdStr
[1], ".Month");
2980 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2981 if (VarIdStr
[2] != NULL
) {
2982 strcpy (VarIdStr
[2], BaseVarId
);
2983 strcat (VarIdStr
[2], ".Day");
2986 Len
= strlen (Name
);
2988 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2989 if (VarIdStr
[0] != NULL
) {
2990 strcpy (VarIdStr
[0], Name
);
2991 strcat (VarIdStr
[0], ".Year");
2993 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2994 if (VarIdStr
[1] != NULL
) {
2995 strcpy (VarIdStr
[1], Name
);
2996 strcat (VarIdStr
[1], ".Month");
2998 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2999 if (VarIdStr
[2] != NULL
) {
3000 strcpy (VarIdStr
[2], Name
);
3001 strcat (VarIdStr
[2], ".Day");
3005 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
3008 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
3011 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
3015 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3016 QuestionId
= GetFreeQuestionId ();
3018 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3021 MarkQuestionIdUsed (QuestionId
);
3024 pNode
[0]->mQuestionId
= QuestionId
;
3025 pNode
[1]->mQuestionId
= QuestionId
;
3026 pNode
[2]->mQuestionId
= QuestionId
;
3027 pNode
[0]->mQtype
= QUESTION_DATE
;
3028 pNode
[1]->mQtype
= QUESTION_DATE
;
3029 pNode
[2]->mQtype
= QUESTION_DATE
;
3030 pNode
[0]->mNext
= pNode
[1];
3031 pNode
[1]->mNext
= pNode
[2];
3032 pNode
[2]->mNext
= mQuestionList
;
3033 mQuestionList
= pNode
[0];
3035 for (Index
= 0; Index
< 3; Index
++) {
3036 if (VarIdStr
[Index
] != NULL
) {
3037 delete[] VarIdStr
[Index
];
3038 VarIdStr
[Index
] = NULL
;
3042 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3043 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3044 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3049 for (Index
= 0; Index
< 3; Index
++) {
3050 if (pNode
[Index
] != NULL
) {
3051 delete pNode
[Index
];
3054 if (VarIdStr
[Index
] != NULL
) {
3055 delete[] VarIdStr
[Index
];
3056 VarIdStr
[Index
] = NULL
;
3062 CVfrQuestionDB::RegisterOldTimeQuestion (
3063 IN CHAR8
*HourVarId
,
3064 IN CHAR8
*MinuteVarId
,
3065 IN CHAR8
*SecondVarId
,
3066 IN OUT EFI_QUESTION_ID
&QuestionId
3069 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3072 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
3076 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
3079 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
3082 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
3086 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3087 QuestionId
= GetFreeQuestionId ();
3089 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3092 MarkQuestionIdUsed (QuestionId
);
3095 pNode
[0]->mQuestionId
= QuestionId
;
3096 pNode
[1]->mQuestionId
= QuestionId
;
3097 pNode
[2]->mQuestionId
= QuestionId
;
3098 pNode
[0]->mQtype
= QUESTION_TIME
;
3099 pNode
[1]->mQtype
= QUESTION_TIME
;
3100 pNode
[2]->mQtype
= QUESTION_TIME
;
3101 pNode
[0]->mNext
= pNode
[1];
3102 pNode
[1]->mNext
= pNode
[2];
3103 pNode
[2]->mNext
= mQuestionList
;
3104 mQuestionList
= pNode
[0];
3106 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3107 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3108 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3113 for (Index
= 0; Index
< 3; Index
++) {
3114 if (pNode
[Index
] != NULL
) {
3115 delete pNode
[Index
];
3118 QuestionId
= EFI_QUESTION_ID_INVALID
;
3122 CVfrQuestionDB::RegisterNewTimeQuestion (
3124 IN CHAR8
*BaseVarId
,
3125 IN OUT EFI_QUESTION_ID
&QuestionId
3128 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3130 CHAR8
*VarIdStr
[3] = {NULL
, };
3133 if (BaseVarId
== NULL
&& Name
== NULL
) {
3134 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3135 QuestionId
= GetFreeQuestionId ();
3137 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3140 MarkQuestionIdUsed (QuestionId
);
3145 if (BaseVarId
!= NULL
) {
3146 Len
= strlen (BaseVarId
);
3148 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3149 if (VarIdStr
[0] != NULL
) {
3150 strcpy (VarIdStr
[0], BaseVarId
);
3151 strcat (VarIdStr
[0], ".Hour");
3153 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3154 if (VarIdStr
[1] != NULL
) {
3155 strcpy (VarIdStr
[1], BaseVarId
);
3156 strcat (VarIdStr
[1], ".Minute");
3158 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3159 if (VarIdStr
[2] != NULL
) {
3160 strcpy (VarIdStr
[2], BaseVarId
);
3161 strcat (VarIdStr
[2], ".Second");
3164 Len
= strlen (Name
);
3166 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3167 if (VarIdStr
[0] != NULL
) {
3168 strcpy (VarIdStr
[0], Name
);
3169 strcat (VarIdStr
[0], ".Hour");
3171 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3172 if (VarIdStr
[1] != NULL
) {
3173 strcpy (VarIdStr
[1], Name
);
3174 strcat (VarIdStr
[1], ".Minute");
3176 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3177 if (VarIdStr
[2] != NULL
) {
3178 strcpy (VarIdStr
[2], Name
);
3179 strcat (VarIdStr
[2], ".Second");
3183 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
3186 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
3189 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
3193 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3194 QuestionId
= GetFreeQuestionId ();
3196 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3199 MarkQuestionIdUsed (QuestionId
);
3202 pNode
[0]->mQuestionId
= QuestionId
;
3203 pNode
[1]->mQuestionId
= QuestionId
;
3204 pNode
[2]->mQuestionId
= QuestionId
;
3205 pNode
[0]->mQtype
= QUESTION_TIME
;
3206 pNode
[1]->mQtype
= QUESTION_TIME
;
3207 pNode
[2]->mQtype
= QUESTION_TIME
;
3208 pNode
[0]->mNext
= pNode
[1];
3209 pNode
[1]->mNext
= pNode
[2];
3210 pNode
[2]->mNext
= mQuestionList
;
3211 mQuestionList
= pNode
[0];
3213 for (Index
= 0; Index
< 3; Index
++) {
3214 if (VarIdStr
[Index
] != NULL
) {
3215 delete[] VarIdStr
[Index
];
3216 VarIdStr
[Index
] = NULL
;
3220 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3221 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3222 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3227 for (Index
= 0; Index
< 3; Index
++) {
3228 if (pNode
[Index
] != NULL
) {
3229 delete pNode
[Index
];
3232 if (VarIdStr
[Index
] != NULL
) {
3233 delete[] VarIdStr
[Index
];
3234 VarIdStr
[Index
] = NULL
;
3240 CVfrQuestionDB::RegisterRefQuestion (
3242 IN CHAR8
*BaseVarId
,
3243 IN OUT EFI_QUESTION_ID
&QuestionId
3246 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3248 CHAR8
*VarIdStr
[4] = {NULL
, };
3251 if (BaseVarId
== NULL
&& Name
== NULL
) {
3255 if (BaseVarId
!= NULL
) {
3256 Len
= strlen (BaseVarId
);
3258 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3259 if (VarIdStr
[0] != NULL
) {
3260 strcpy (VarIdStr
[0], BaseVarId
);
3261 strcat (VarIdStr
[0], ".QuestionId");
3263 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3264 if (VarIdStr
[1] != NULL
) {
3265 strcpy (VarIdStr
[1], BaseVarId
);
3266 strcat (VarIdStr
[1], ".FormId");
3268 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3269 if (VarIdStr
[2] != NULL
) {
3270 strcpy (VarIdStr
[2], BaseVarId
);
3271 strcat (VarIdStr
[2], ".FormSetGuid");
3273 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3274 if (VarIdStr
[3] != NULL
) {
3275 strcpy (VarIdStr
[3], BaseVarId
);
3276 strcat (VarIdStr
[3], ".DevicePath");
3279 Len
= strlen (Name
);
3281 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3282 if (VarIdStr
[0] != NULL
) {
3283 strcpy (VarIdStr
[0], Name
);
3284 strcat (VarIdStr
[0], ".QuestionId");
3286 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3287 if (VarIdStr
[1] != NULL
) {
3288 strcpy (VarIdStr
[1], Name
);
3289 strcat (VarIdStr
[1], ".FormId");
3291 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3292 if (VarIdStr
[2] != NULL
) {
3293 strcpy (VarIdStr
[2], Name
);
3294 strcat (VarIdStr
[2], ".FormSetGuid");
3296 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3297 if (VarIdStr
[3] != NULL
) {
3298 strcpy (VarIdStr
[3], Name
);
3299 strcat (VarIdStr
[3], ".DevicePath");
3303 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3306 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3309 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3312 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3316 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3317 QuestionId
= GetFreeQuestionId ();
3319 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3322 MarkQuestionIdUsed (QuestionId
);
3325 pNode
[0]->mQuestionId
= QuestionId
;
3326 pNode
[1]->mQuestionId
= QuestionId
;
3327 pNode
[2]->mQuestionId
= QuestionId
;
3328 pNode
[3]->mQuestionId
= QuestionId
;
3329 pNode
[0]->mQtype
= QUESTION_REF
;
3330 pNode
[1]->mQtype
= QUESTION_REF
;
3331 pNode
[2]->mQtype
= QUESTION_REF
;
3332 pNode
[3]->mQtype
= QUESTION_REF
;
3333 pNode
[0]->mNext
= pNode
[1];
3334 pNode
[1]->mNext
= pNode
[2];
3335 pNode
[2]->mNext
= pNode
[3];
3336 pNode
[3]->mNext
= mQuestionList
;
3337 mQuestionList
= pNode
[0];
3339 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3340 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3341 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3342 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3347 for (Index
= 0; Index
< 4; Index
++) {
3348 if (pNode
[Index
] != NULL
) {
3349 delete pNode
[Index
];
3352 if (VarIdStr
[Index
] != NULL
) {
3353 delete VarIdStr
[Index
];
3359 CVfrQuestionDB::UpdateQuestionId (
3360 IN EFI_QUESTION_ID QId
,
3361 IN EFI_QUESTION_ID NewQId
3364 SVfrQuestionNode
*pNode
= NULL
;
3366 if (QId
== NewQId
) {
3368 return VFR_RETURN_SUCCESS
;
3372 // For Framework Vfr, don't check question ID conflict.
3374 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3375 return VFR_RETURN_REDEFINED
;
3378 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3379 if (pNode
->mQuestionId
== QId
) {
3384 if (pNode
== NULL
) {
3385 return VFR_RETURN_UNDEFINED
;
3388 MarkQuestionIdUnused (QId
);
3389 pNode
->mQuestionId
= NewQId
;
3390 MarkQuestionIdUsed (NewQId
);
3392 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3394 return VFR_RETURN_SUCCESS
;
3398 CVfrQuestionDB::GetQuestionId (
3401 OUT EFI_QUESTION_ID
&QuestionId
,
3402 OUT UINT32
&BitMask
,
3403 OUT EFI_QUESION_TYPE
*QType
3406 SVfrQuestionNode
*pNode
;
3408 QuestionId
= EFI_QUESTION_ID_INVALID
;
3409 BitMask
= 0x00000000;
3410 if (QType
!= NULL
) {
3411 *QType
= QUESTION_NORMAL
;
3414 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3418 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3420 if (strcmp (pNode
->mName
, Name
) != 0) {
3425 if (VarIdStr
!= NULL
) {
3426 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3431 QuestionId
= pNode
->mQuestionId
;
3432 BitMask
= pNode
->mBitMask
;
3433 if (QType
!= NULL
) {
3434 *QType
= pNode
->mQtype
;
3443 CVfrQuestionDB::FindQuestion (
3444 IN EFI_QUESTION_ID QuestionId
3447 SVfrQuestionNode
*pNode
;
3449 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3450 return VFR_RETURN_INVALID_PARAMETER
;
3453 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3454 if (pNode
->mQuestionId
== QuestionId
) {
3455 return VFR_RETURN_SUCCESS
;
3459 return VFR_RETURN_UNDEFINED
;
3463 CVfrQuestionDB::FindQuestion (
3467 SVfrQuestionNode
*pNode
;
3470 return VFR_RETURN_FATAL_ERROR
;
3473 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3474 if (strcmp (pNode
->mName
, Name
) == 0) {
3475 return VFR_RETURN_SUCCESS
;
3479 return VFR_RETURN_UNDEFINED
;
3482 CVfrStringDB::CVfrStringDB ()
3484 mStringFileName
= NULL
;
3487 CVfrStringDB::~CVfrStringDB ()
3489 if (mStringFileName
!= NULL
) {
3490 delete[] mStringFileName
;
3492 mStringFileName
= NULL
;
3497 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3501 if (StringFileName
== NULL
) {
3505 if (mStringFileName
!= NULL
) {
3506 delete[] mStringFileName
;
3509 FileLen
= strlen (StringFileName
) + 1;
3510 mStringFileName
= new CHAR8
[FileLen
];
3511 if (mStringFileName
== NULL
) {
3515 strcpy (mStringFileName
, StringFileName
);
3516 mStringFileName
[FileLen
- 1] = '\0';
3521 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3522 from a set of supported languages.
3524 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3525 contains a set of language codes.
3526 @param[in] Language A variable that contains pointers to Null-terminated
3527 ASCII strings that contain one language codes.
3529 @retval FALSE The best matching language could not be found in SupportedLanguages.
3530 @retval TRUE The best matching language could be found in SupportedLanguages.
3534 CVfrStringDB::GetBestLanguage (
3535 IN CONST CHAR8
*SupportedLanguages
,
3539 UINTN CompareLength
;
3540 UINTN LanguageLength
;
3541 CONST CHAR8
*Supported
;
3543 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3548 // Determine the length of the first RFC 4646 language code in Language
3550 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3553 // Trim back the length of Language used until it is empty
3555 while (LanguageLength
> 0) {
3557 // Loop through all language codes in SupportedLanguages
3559 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3561 // Skip ';' characters in Supported
3563 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3565 // Determine the length of the next language code in Supported
3567 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3569 // If Language is longer than the Supported, then skip to the next language
3571 if (LanguageLength
> CompareLength
) {
3576 // See if the first LanguageLength characters in Supported match Language
3578 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3584 // Trim Language from the right to the next '-' character
3586 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3590 // No matches were found
3597 CVfrStringDB::GetVarStoreNameFormStringId (
3598 IN EFI_STRING_ID StringId
3601 FILE *pInFile
= NULL
;
3606 CHAR16
*UnicodeString
;
3607 CHAR8
*VarStoreName
= NULL
;
3611 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3613 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3615 if (mStringFileName
== NULL
) {
3619 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3626 fseek (pInFile
, 0, SEEK_END
);
3627 Length
= ftell (pInFile
);
3628 fseek (pInFile
, 0, SEEK_SET
);
3633 StringPtr
= new UINT8
[Length
];
3634 if (StringPtr
== NULL
) {
3638 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3641 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3643 // Check the String package.
3645 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3651 // Search the language, get best language base on RFC 4647 matching algorithm.
3653 Current
= StringPtr
;
3654 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3655 Current
+= PkgHeader
->Header
.Length
;
3656 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3658 // If can't find string package base on language, just return the first string package.
3660 if (Current
- StringPtr
>= Length
) {
3661 Current
= StringPtr
;
3662 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3667 Current
+= PkgHeader
->HdrSize
;
3669 // Find the string block according the stringId.
3671 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3672 if (Status
!= EFI_SUCCESS
) {
3678 // Get varstore name according the string type.
3680 switch (BlockType
) {
3681 case EFI_HII_SIBT_STRING_SCSU
:
3682 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3683 case EFI_HII_SIBT_STRINGS_SCSU
:
3684 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3685 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3686 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3687 strcpy (VarStoreName
, StringName
);
3689 case EFI_HII_SIBT_STRING_UCS2
:
3690 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3691 case EFI_HII_SIBT_STRINGS_UCS2
:
3692 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3693 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3694 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3695 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3696 VarStoreName
= DestTmp
;
3697 while (*UnicodeString
!= '\0') {
3698 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3708 return VarStoreName
;
3712 CVfrStringDB::FindStringBlock (
3713 IN UINT8
*StringData
,
3714 IN EFI_STRING_ID StringId
,
3715 OUT UINT32
*StringTextOffset
,
3716 OUT UINT8
*BlockType
3720 EFI_STRING_ID CurrentStringId
;
3723 UINT8
*StringTextPtr
;
3728 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3732 CurrentStringId
= 1;
3735 // Parse the string blocks to get the string text and font.
3737 BlockHdr
= StringData
;
3740 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3741 switch (*BlockHdr
) {
3742 case EFI_HII_SIBT_STRING_SCSU
:
3743 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3744 StringTextPtr
= BlockHdr
+ Offset
;
3745 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3749 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3750 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3751 StringTextPtr
= BlockHdr
+ Offset
;
3752 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3756 case EFI_HII_SIBT_STRINGS_SCSU
:
3757 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3758 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3759 BlockSize
+= StringTextPtr
- BlockHdr
;
3761 for (Index
= 0; Index
< StringCount
; Index
++) {
3762 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3763 if (CurrentStringId
== StringId
) {
3764 *BlockType
= *BlockHdr
;
3765 *StringTextOffset
= StringTextPtr
- StringData
;
3768 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3773 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3776 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3779 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3780 BlockSize
+= StringTextPtr
- BlockHdr
;
3782 for (Index
= 0; Index
< StringCount
; Index
++) {
3783 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3784 if (CurrentStringId
== StringId
) {
3785 *BlockType
= *BlockHdr
;
3786 *StringTextOffset
= StringTextPtr
- StringData
;
3789 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3794 case EFI_HII_SIBT_STRING_UCS2
:
3795 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3796 StringTextPtr
= BlockHdr
+ Offset
;
3798 // Use StringSize to store the size of the specified string, including the NULL
3801 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3802 BlockSize
+= Offset
+ StringSize
;
3806 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3807 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3808 StringTextPtr
= BlockHdr
+ Offset
;
3810 // Use StrSize to store the size of the specified string, including the NULL
3813 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3814 BlockSize
+= Offset
+ StringSize
;
3818 case EFI_HII_SIBT_STRINGS_UCS2
:
3819 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3820 StringTextPtr
= BlockHdr
+ Offset
;
3821 BlockSize
+= Offset
;
3822 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3823 for (Index
= 0; Index
< StringCount
; Index
++) {
3824 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3825 BlockSize
+= StringSize
;
3826 if (CurrentStringId
== StringId
) {
3827 *BlockType
= *BlockHdr
;
3828 *StringTextOffset
= StringTextPtr
- StringData
;
3831 StringTextPtr
= StringTextPtr
+ StringSize
;
3836 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3837 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3838 StringTextPtr
= BlockHdr
+ Offset
;
3839 BlockSize
+= Offset
;
3842 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3845 for (Index
= 0; Index
< StringCount
; Index
++) {
3846 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3847 BlockSize
+= StringSize
;
3848 if (CurrentStringId
== StringId
) {
3849 *BlockType
= *BlockHdr
;
3850 *StringTextOffset
= StringTextPtr
- StringData
;
3853 StringTextPtr
= StringTextPtr
+ StringSize
;
3858 case EFI_HII_SIBT_DUPLICATE
:
3859 if (CurrentStringId
== StringId
) {
3861 // Incoming StringId is an id of a duplicate string block.
3862 // Update the StringId to be the previous string block.
3863 // Go back to the header of string block to search.
3867 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3868 sizeof (EFI_STRING_ID
)
3870 CurrentStringId
= 1;
3873 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3878 case EFI_HII_SIBT_SKIP1
:
3879 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3880 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3881 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3884 case EFI_HII_SIBT_SKIP2
:
3885 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3886 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3887 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3890 case EFI_HII_SIBT_EXT1
:
3893 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3896 BlockSize
+= Length8
;
3899 case EFI_HII_SIBT_EXT2
:
3900 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3901 BlockSize
+= Ext2
.Length
;
3904 case EFI_HII_SIBT_EXT4
:
3907 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3911 BlockSize
+= Length32
;
3918 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3919 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3920 *BlockType
= *BlockHdr
;
3922 if (StringId
== CurrentStringId
- 1) {
3924 // if only one skip item, return EFI_NOT_FOUND.
3926 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3927 return EFI_NOT_FOUND
;
3933 if (StringId
< CurrentStringId
- 1) {
3934 return EFI_NOT_FOUND
;
3937 BlockHdr
= StringData
+ BlockSize
;
3940 return EFI_NOT_FOUND
;
3944 CVfrStringDB::GetUnicodeStringTextSize (
3951 StringSize
= sizeof (CHAR16
);
3952 StringPtr
= (UINT16
*)StringSrc
;
3953 while (*StringPtr
++ != L
'\0') {
3954 StringSize
+= sizeof (CHAR16
);
3960 BOOLEAN VfrCompatibleMode
= FALSE
;
3962 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3963 CVfrDefaultStore gCVfrDefaultStore
;
3964 CVfrDataStorage gCVfrDataStorage
;