3 Vfr common library functions.
5 Copyright (c) 2004 - 2018, 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.
19 #include "CommonLib.h"
20 #include "VfrUtilityLib.h"
21 #include "VfrFormPkg.h"
24 CVfrBinaryOutput::WriteLine (
27 IN CONST CHAR8
*LineHeader
,
34 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
38 for (Index
= 0; Index
< BlkSize
; Index
++) {
39 if ((Index
% LineBytes
) == 0) {
40 fprintf (pFile
, "\n%s", LineHeader
);
42 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
47 CVfrBinaryOutput::WriteEnd (
50 IN CONST CHAR8
*LineHeader
,
57 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
61 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
62 if ((Index
% LineBytes
) == 0) {
63 fprintf (pFile
, "\n%s", LineHeader
);
65 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
68 if ((Index
% LineBytes
) == 0) {
69 fprintf (pFile
, "\n%s", LineHeader
);
71 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
74 SConfigInfo::SConfigInfo (
78 IN EFI_IFR_TYPE_VALUE Value
83 mWidth
= (UINT16
)Width
;
84 mValue
= new UINT8
[mWidth
];
90 case EFI_IFR_TYPE_NUM_SIZE_8
:
91 memcpy (mValue
, &Value
.u8
, mWidth
);
93 case EFI_IFR_TYPE_NUM_SIZE_16
:
94 memcpy (mValue
, &Value
.u16
, mWidth
);
96 case EFI_IFR_TYPE_NUM_SIZE_32
:
97 memcpy (mValue
, &Value
.u32
, mWidth
);
99 case EFI_IFR_TYPE_NUM_SIZE_64
:
100 memcpy (mValue
, &Value
.u64
, mWidth
);
102 case EFI_IFR_TYPE_BOOLEAN
:
103 memcpy (mValue
, &Value
.b
, mWidth
);
105 case EFI_IFR_TYPE_TIME
:
106 memcpy (mValue
, &Value
.time
, mWidth
);
108 case EFI_IFR_TYPE_DATE
:
109 memcpy (mValue
, &Value
.date
, mWidth
);
111 case EFI_IFR_TYPE_STRING
:
112 memcpy (mValue
, &Value
.string
, mWidth
);
114 case EFI_IFR_TYPE_BUFFER
:
115 memcpy (mValue
, &Value
.u8
, mWidth
);
118 case EFI_IFR_TYPE_OTHER
:
123 SConfigInfo::~SConfigInfo (
127 ARRAY_SAFE_FREE (mValue
);
130 SConfigItem::SConfigItem (
143 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
144 strcpy (mName
, Name
);
149 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
150 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
155 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
161 SConfigItem::SConfigItem (
168 IN EFI_IFR_TYPE_VALUE Value
178 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
179 strcpy (mName
, Name
);
184 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
185 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
190 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
195 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
198 SConfigItem::~SConfigItem (
204 ARRAY_SAFE_FREE (mName
);
205 ARRAY_SAFE_FREE (mGuid
);
206 ARRAY_SAFE_FREE (mId
);
207 while (mInfoStrList
!= NULL
) {
209 mInfoStrList
= mInfoStrList
->mNext
;
211 BUFFER_SAFE_FREE (Info
);
216 CVfrBufferConfig::Register (
224 if (Select (Name
, Guid
) == 0) {
228 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
232 if (mItemListHead
== NULL
) {
233 mItemListHead
= pNew
;
234 mItemListTail
= pNew
;
236 mItemListTail
->mNext
= pNew
;
237 mItemListTail
= pNew
;
245 CVfrBufferConfig::Open (
249 mItemListPos
= mItemListHead
;
253 CVfrBufferConfig::Eof(
257 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
261 CVfrBufferConfig::Select (
269 if (Name
== NULL
|| Guid
== NULL
) {
270 mItemListPos
= mItemListHead
;
273 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
274 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
279 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
282 } else if (p
->mId
!= NULL
) {
295 CVfrBufferConfig::Write (
303 IN EFI_IFR_TYPE_VALUE Value
310 if ((Ret
= Select (Name
, Guid
)) != 0) {
316 if (Select (Name
, Guid
, Id
) != 0) {
317 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
320 if (mItemListHead
== NULL
) {
321 mItemListHead
= pItem
;
322 mItemListTail
= pItem
;
324 mItemListTail
->mNext
= pItem
;
325 mItemListTail
= pItem
;
327 mItemListPos
= pItem
;
329 // tranverse the list to find out if there's already the value for the same offset
330 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
331 if (pInfo
->mOffset
== Offset
) {
335 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
338 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
339 mItemListPos
->mInfoStrList
= pInfo
;
344 if (mItemListHead
== mItemListPos
) {
345 mItemListHead
= mItemListPos
->mNext
;
350 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
353 pItem
->mNext
= mItemListPos
->mNext
;
354 if (mItemListTail
== mItemListPos
) {
355 mItemListTail
= pItem
;
358 mItemListPos
= pItem
->mNext
;
361 case 'i' : // set info
362 if (mItemListPos
->mId
!= NULL
) {
363 delete[] mItemListPos
->mId
;
365 mItemListPos
->mId
= NULL
;
367 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
370 strcpy (mItemListPos
->mId
, Id
);
383 CVfrBufferConfig::Close (
390 #define BYTES_PRE_LINE 0x10
393 CVfrBufferConfig::OutputCFile (
398 CVfrBinaryOutput Output
;
407 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
408 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
411 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
413 TotalLen
= sizeof (UINT32
);
414 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
415 TotalLen
+= sizeof (UINT16
) * 2;
417 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
419 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
420 fprintf (pFile
, "\n");
421 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
422 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
424 fprintf (pFile
, "\n};\n");
427 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
428 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
429 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
431 TotalLen
= sizeof (UINT32
);
432 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
433 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
435 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
437 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
438 fprintf (pFile
, "\n");
439 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
440 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
441 if (Info
->mNext
== NULL
) {
442 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
444 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
447 fprintf (pFile
, "\n};\n");
452 CVfrBufferConfig::CVfrBufferConfig (
456 mItemListHead
= NULL
;
457 mItemListTail
= NULL
;
461 CVfrBufferConfig::~CVfrBufferConfig (
467 while (mItemListHead
!= NULL
) {
469 mItemListHead
= mItemListHead
->mNext
;
473 mItemListHead
= NULL
;
474 mItemListTail
= NULL
;
478 CVfrBufferConfig gCVfrBufferConfig
;
481 CONST CHAR8
*mTypeName
;
485 } gInternalTypesTable
[] = {
486 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
487 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
488 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
489 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
490 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
491 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
492 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
493 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
494 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
495 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
506 if (TypeName
== NULL
) {
510 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
511 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
528 while (*Str
&& *Str
== ' ') {
531 while (*Str
&& *Str
== '0') {
534 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
551 Str
= TrimHex (Str
, &IsHex
);
552 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
554 // BUG: does not handle overflow here
556 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
558 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
559 Value
+= (c
- 'a' + 10);
561 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
562 Value
+= (c
- 'A' + 10);
564 if (c
>= '0' && c
<= '9') {
573 CVfrVarDataTypeDB::RegisterNewType (
577 New
->mNext
= mDataTypeList
;
582 CVfrVarDataTypeDB::ExtractStructTypeName (
588 return VFR_RETURN_FATAL_ERROR
;
591 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
597 if (*VarStr
== '.') {
601 return VFR_RETURN_SUCCESS
;
605 Check whether the DataType contain bit field.
607 @param TypeName The name of the type.
611 CVfrVarDataTypeDB::DataTypeHasBitField (
615 SVfrDataType
*pType
= NULL
;
618 GetDataType (TypeName
, &pType
);
623 for (pTmp
= pType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
624 if (pTmp
->mIsBitField
) {
632 Check whether the field is bit field or not.
634 @param VarStr Point to the field name which may contain the structure name.
638 CVfrVarDataTypeDB::IsThisBitField (
642 CHAR8 FName
[MAX_NAME_LEN
];
643 CHAR8 TName
[MAX_NAME_LEN
];
645 SVfrDataType
*pType
= NULL
;
646 SVfrDataField
*pField
= NULL
;
648 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
649 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
651 while (*VarStr
!= '\0') {
652 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
653 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
654 pType
= pField
->mFieldType
;
656 if (pField
!= NULL
&& pField
->mIsBitField
) {
664 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
671 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
673 ArrayIdx
= INVALID_ARRAY_INDEX
;
676 return VFR_RETURN_FATAL_ERROR
;
679 while((*VarStr
!= '\0') &&
693 return VFR_RETURN_SUCCESS
;
696 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
697 ArrayStr
[Idx
] = *VarStr
;
699 ArrayStr
[Idx
] = '\0';
701 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
702 return VFR_RETURN_DATA_STRING_ERROR
;
704 ArrayIdx
= _STR2U32 (ArrayStr
);
705 if (*VarStr
== ']') {
708 if (*VarStr
== '.') {
711 return VFR_RETURN_SUCCESS
;
713 return VFR_RETURN_DATA_STRING_ERROR
;
716 return VFR_RETURN_SUCCESS
;
720 CVfrVarDataTypeDB::GetTypeField (
721 IN CONST CHAR8
*FName
,
722 IN SVfrDataType
*Type
,
723 OUT SVfrDataField
*&Field
726 SVfrDataField
*pField
= NULL
;
728 if ((FName
== NULL
) || (Type
== NULL
)) {
729 return VFR_RETURN_FATAL_ERROR
;
732 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
734 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
735 // add code to adjust it.
737 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
738 if (strcmp (FName
, "Hour") == 0) {
740 } else if (strcmp (FName
, "Minute") == 0) {
742 } else if (strcmp (FName
, "Second") == 0) {
747 if (strcmp (pField
->mFieldName
, FName
) == 0) {
749 return VFR_RETURN_SUCCESS
;
753 return VFR_RETURN_UNDEFINED
;
757 CVfrVarDataTypeDB::GetFieldOffset (
758 IN SVfrDataField
*Field
,
761 IN BOOLEAN IsBitField
765 return VFR_RETURN_FATAL_ERROR
;
769 // Framework Vfr file Array Index is from 1.
770 // But Uefi Vfr file Array Index is from 0.
772 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
774 return VFR_RETURN_ERROR_ARRARY_NUM
;
776 ArrayIdx
= ArrayIdx
- 1;
779 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
780 return VFR_RETURN_ERROR_ARRARY_NUM
;
784 // Be compatible with the current usage
785 // If ArraryIdx is not specified, the first one is used.
787 // if ArrayNum is larger than zero, ArraryIdx must be specified.
789 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
790 // return VFR_RETURN_ERROR_ARRARY_NUM;
794 Offset
= Field
->mBitOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
) * 8;
796 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
798 return VFR_RETURN_SUCCESS
;
802 CVfrVarDataTypeDB::GetFieldWidth (
803 IN SVfrDataField
*Field
810 return Field
->mFieldType
->mType
;
814 CVfrVarDataTypeDB::GetFieldSize (
815 IN SVfrDataField
*Field
,
821 return VFR_RETURN_FATAL_ERROR
;
824 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
825 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
828 return Field
->mBitWidth
;
830 return Field
->mFieldType
->mTotalSize
;
836 CVfrVarDataTypeDB::InternalTypesListInit (
840 SVfrDataType
*New
= NULL
;
843 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
844 New
= new SVfrDataType
;
846 assert (strlen (gInternalTypesTable
[Index
].mTypeName
) < MAX_NAME_LEN
);
847 strncpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
, MAX_NAME_LEN
- 1);
848 New
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
849 New
->mType
= gInternalTypesTable
[Index
].mType
;
850 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
851 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
852 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
853 SVfrDataField
*pYearField
= new SVfrDataField
;
854 SVfrDataField
*pMonthField
= new SVfrDataField
;
855 SVfrDataField
*pDayField
= new SVfrDataField
;
857 strcpy (pYearField
->mFieldName
, "Year");
858 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
859 pYearField
->mOffset
= 0;
860 pYearField
->mNext
= pMonthField
;
861 pYearField
->mArrayNum
= 0;
862 pYearField
->mIsBitField
= FALSE
;
864 strcpy (pMonthField
->mFieldName
, "Month");
865 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
866 pMonthField
->mOffset
= 2;
867 pMonthField
->mNext
= pDayField
;
868 pMonthField
->mArrayNum
= 0;
869 pMonthField
->mIsBitField
= FALSE
;
871 strcpy (pDayField
->mFieldName
, "Day");
872 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
873 pDayField
->mOffset
= 3;
874 pDayField
->mNext
= NULL
;
875 pDayField
->mArrayNum
= 0;
876 pDayField
->mIsBitField
= FALSE
;
878 New
->mMembers
= pYearField
;
879 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
880 SVfrDataField
*pHoursField
= new SVfrDataField
;
881 SVfrDataField
*pMinutesField
= new SVfrDataField
;
882 SVfrDataField
*pSecondsField
= new SVfrDataField
;
884 strcpy (pHoursField
->mFieldName
, "Hours");
885 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
886 pHoursField
->mOffset
= 0;
887 pHoursField
->mNext
= pMinutesField
;
888 pHoursField
->mArrayNum
= 0;
889 pHoursField
->mIsBitField
= FALSE
;
891 strcpy (pMinutesField
->mFieldName
, "Minutes");
892 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
893 pMinutesField
->mOffset
= 1;
894 pMinutesField
->mNext
= pSecondsField
;
895 pMinutesField
->mArrayNum
= 0;
896 pMinutesField
->mIsBitField
= FALSE
;
898 strcpy (pSecondsField
->mFieldName
, "Seconds");
899 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
900 pSecondsField
->mOffset
= 2;
901 pSecondsField
->mNext
= NULL
;
902 pSecondsField
->mArrayNum
= 0;
903 pSecondsField
->mIsBitField
= FALSE
;
905 New
->mMembers
= pHoursField
;
906 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
907 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
908 SVfrDataField
*pFormIdField
= new SVfrDataField
;
909 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
910 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
912 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
913 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
914 pQuestionIdField
->mOffset
= 0;
915 pQuestionIdField
->mNext
= pFormIdField
;
916 pQuestionIdField
->mArrayNum
= 0;
917 pQuestionIdField
->mIsBitField
= FALSE
;
919 strcpy (pFormIdField
->mFieldName
, "FormId");
920 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
921 pFormIdField
->mOffset
= 2;
922 pFormIdField
->mNext
= pFormSetGuidField
;
923 pFormIdField
->mArrayNum
= 0;
924 pFormIdField
->mIsBitField
= FALSE
;
926 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
927 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
928 pFormSetGuidField
->mOffset
= 4;
929 pFormSetGuidField
->mNext
= pDevicePathField
;
930 pFormSetGuidField
->mArrayNum
= 0;
931 pFormSetGuidField
->mIsBitField
= FALSE
;
933 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
934 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
935 pDevicePathField
->mOffset
= 20;
936 pDevicePathField
->mNext
= NULL
;
937 pDevicePathField
->mArrayNum
= 0;
938 pDevicePathField
->mIsBitField
= FALSE
;
940 New
->mMembers
= pQuestionIdField
;
942 New
->mMembers
= NULL
;
945 RegisterNewType (New
);
951 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
955 mDataTypeList
= NULL
;
957 mCurrDataField
= NULL
;
958 mPackAlign
= DEFAULT_PACK_ALIGN
;
960 mFirstNewDataTypeName
= NULL
;
961 mCurrDataType
= NULL
;
963 InternalTypesListInit ();
966 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
971 SVfrDataField
*pField
;
972 SVfrPackStackNode
*pPack
;
974 if (mNewDataType
!= NULL
) {
978 while (mDataTypeList
!= NULL
) {
979 pType
= mDataTypeList
;
980 mDataTypeList
= mDataTypeList
->mNext
;
981 while(pType
->mMembers
!= NULL
) {
982 pField
= pType
->mMembers
;
983 pType
->mMembers
= pType
->mMembers
->mNext
;
989 while (mPackStack
!= NULL
) {
991 mPackStack
= mPackStack
->mNext
;
997 CVfrVarDataTypeDB::Pack (
1000 IN CHAR8
*Identifier
,
1005 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
1007 if (Action
& VFR_PACK_SHOW
) {
1008 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
1009 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
1012 if (Action
& VFR_PACK_PUSH
) {
1013 SVfrPackStackNode
*pNew
= NULL
;
1015 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
1016 return VFR_RETURN_FATAL_ERROR
;
1018 pNew
->mNext
= mPackStack
;
1022 if (Action
& VFR_PACK_POP
) {
1023 SVfrPackStackNode
*pNode
= NULL
;
1025 if (mPackStack
== NULL
) {
1026 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
1029 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1030 if (pNode
->Match (Identifier
) == TRUE
) {
1031 mPackAlign
= pNode
->mNumber
;
1032 mPackStack
= pNode
->mNext
;
1037 if (Action
& VFR_PACK_ASSIGN
) {
1038 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
1039 if ((PackAlign
== 0) || (PackAlign
> 16)) {
1040 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
1042 mPackAlign
= PackAlign
;
1046 return VFR_RETURN_SUCCESS
;
1050 CVfrVarDataTypeDB::DeclareDataTypeBegin (
1054 SVfrDataType
*pNewType
= NULL
;
1056 pNewType
= new SVfrDataType
;
1057 pNewType
->mTypeName
[0] = '\0';
1058 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
1059 pNewType
->mAlign
= DEFAULT_ALIGN
;
1060 pNewType
->mTotalSize
= 0;
1061 pNewType
->mMembers
= NULL
;
1062 pNewType
->mNext
= NULL
;
1063 pNewType
->mHasBitField
= FALSE
;
1065 mNewDataType
= pNewType
;
1069 CVfrVarDataTypeDB::SetNewTypeName (
1073 SVfrDataType
*pType
;
1075 if (mNewDataType
== NULL
) {
1076 return VFR_RETURN_ERROR_SKIPED
;
1078 if (TypeName
== NULL
) {
1079 return VFR_RETURN_FATAL_ERROR
;
1081 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
1082 return VFR_RETURN_INVALID_PARAMETER
;
1085 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1086 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1087 return VFR_RETURN_REDEFINED
;
1091 strncpy(mNewDataType
->mTypeName
, TypeName
, MAX_NAME_LEN
- 1);
1092 mNewDataType
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
1093 return VFR_RETURN_SUCCESS
;
1097 Record the bit field info in the data type.
1099 @param FieldName Point to the field name.
1100 @param TypeName Point to the type name.
1101 @param Width The bit width.
1102 @param FieldInUnion The filed is in Union type or Structure type.
1106 CVfrVarDataTypeDB::DataTypeAddBitField (
1107 IN CHAR8
*FieldName
,
1110 IN BOOLEAN FieldInUnion
1113 SVfrDataField
*pNewField
= NULL
;
1114 SVfrDataType
*pFieldType
= NULL
;
1115 SVfrDataField
*pTmp
;
1117 UINT32 MaxDataTypeSize
;
1118 BOOLEAN UpdateTotalSize
;
1120 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1122 if (Width
> MAX_BIT_WIDTH
) {
1123 return VFR_RETURN_BIT_WIDTH_ERROR
;
1126 if (Width
> pFieldType
->mTotalSize
* 8) {
1127 return VFR_RETURN_BIT_WIDTH_ERROR
;
1130 if (FieldName
!= NULL
&& strlen (FieldName
) >= MAX_NAME_LEN
) {
1131 return VFR_RETURN_INVALID_PARAMETER
;
1134 if (Width
== 0 && FieldName
!= NULL
) {
1135 return VFR_RETURN_INVALID_PARAMETER
;
1138 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1139 if (FieldName
!= NULL
&& strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1140 return VFR_RETURN_REDEFINED
;
1144 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1145 UpdateTotalSize
= FALSE
;
1147 if ((pNewField
= new SVfrDataField
) == NULL
) {
1148 return VFR_RETURN_OUT_FOR_RESOURCES
;
1151 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1152 if (FieldName
!= NULL
) {
1153 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1154 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1156 pNewField
->mFieldType
= pFieldType
;
1157 pNewField
->mIsBitField
= TRUE
;
1158 pNewField
->mBitWidth
= Width
;
1159 pNewField
->mArrayNum
= 0;
1160 pNewField
->mBitOffset
= 0;
1161 pNewField
->mOffset
= 0;
1163 if (mNewDataType
->mMembers
== NULL
) {
1164 mNewDataType
->mMembers
= pNewField
;
1165 pNewField
->mNext
= NULL
;
1167 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1169 pTmp
->mNext
= pNewField
;
1170 pNewField
->mNext
= NULL
;
1174 pNewField
->mOffset
= 0;
1175 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1176 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1180 // Check whether the bit fileds can be contained within one FieldType.
1182 if (pTmp
!= NULL
&& pTmp
->mIsBitField
&& strcmp (pTmp
->mFieldType
->mTypeName
, pNewField
->mFieldType
->mTypeName
) == 0 &&
1183 (pTmp
->mBitOffset
- pTmp
->mOffset
* 8) + pTmp
->mBitWidth
+ pNewField
->mBitWidth
<= pNewField
->mFieldType
->mTotalSize
* 8) {
1184 pNewField
->mBitOffset
= pTmp
->mBitOffset
+ pTmp
->mBitWidth
;
1185 pNewField
->mOffset
= pTmp
->mOffset
;
1187 // If BitWidth=0,used to force alignment at the next word boundary.
1188 // So make this bit field occupy the remaing bit width of current field type.
1190 if (pNewField
->mBitWidth
== 0) {
1191 pNewField
->mBitWidth
= pNewField
->mFieldType
->mTotalSize
* 8 - (pNewField
->mBitOffset
- pTmp
->mOffset
* 8);
1195 // The bit filed start a new memory
1197 pNewField
->mBitOffset
= mNewDataType
->mTotalSize
* 8;
1198 UpdateTotalSize
= TRUE
;
1202 if (UpdateTotalSize
){
1203 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1204 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1206 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1208 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
);
1211 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1212 mNewDataType
->mHasBitField
= TRUE
;
1213 return VFR_RETURN_SUCCESS
;
1217 CVfrVarDataTypeDB::DataTypeAddField (
1218 IN CHAR8
*FieldName
,
1221 IN BOOLEAN FieldInUnion
1224 SVfrDataField
*pNewField
= NULL
;
1225 SVfrDataType
*pFieldType
= NULL
;
1226 SVfrDataField
*pTmp
;
1228 UINT32 MaxDataTypeSize
;
1230 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1231 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1233 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1234 return VFR_RETURN_INVALID_PARAMETER
;
1237 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1238 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1239 return VFR_RETURN_REDEFINED
;
1243 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1245 if ((pNewField
= new SVfrDataField
) == NULL
) {
1246 return VFR_RETURN_OUT_FOR_RESOURCES
;
1248 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1249 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1250 pNewField
->mFieldType
= pFieldType
;
1251 pNewField
->mArrayNum
= ArrayNum
;
1252 pNewField
->mIsBitField
= FALSE
;
1253 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1254 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1256 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1258 if (mNewDataType
->mMembers
== NULL
) {
1259 mNewDataType
->mMembers
= pNewField
;
1260 pNewField
->mNext
= NULL
;
1262 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1264 pTmp
->mNext
= pNewField
;
1265 pNewField
->mNext
= NULL
;
1268 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1271 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1272 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1274 pNewField
->mOffset
= 0;
1276 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1279 return VFR_RETURN_SUCCESS
;
1283 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1287 if (mNewDataType
->mTypeName
[0] == '\0') {
1291 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1292 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1295 RegisterNewType (mNewDataType
);
1296 if (mFirstNewDataTypeName
== NULL
) {
1297 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1300 mNewDataType
= NULL
;
1304 CVfrVarDataTypeDB::GetDataType (
1306 OUT SVfrDataType
**DataType
1309 SVfrDataType
*pDataType
= NULL
;
1311 if (TypeName
== NULL
) {
1312 return VFR_RETURN_ERROR_SKIPED
;
1315 if (DataType
== NULL
) {
1316 return VFR_RETURN_FATAL_ERROR
;
1321 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1322 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1323 *DataType
= pDataType
;
1324 return VFR_RETURN_SUCCESS
;
1328 return VFR_RETURN_UNDEFINED
;
1332 CVfrVarDataTypeDB::GetDataTypeSize (
1337 SVfrDataType
*pDataType
= NULL
;
1340 return VFR_RETURN_FATAL_ERROR
;
1344 DataType
= DataType
& 0x0F;
1347 // For user defined data type, the size can't be got by this function.
1349 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1350 return VFR_RETURN_SUCCESS
;
1353 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1354 if (DataType
== pDataType
->mType
) {
1355 *Size
= pDataType
->mTotalSize
;
1356 return VFR_RETURN_SUCCESS
;
1360 return VFR_RETURN_UNDEFINED
;
1364 CVfrVarDataTypeDB::GetDataTypeSize (
1369 SVfrDataType
*pDataType
= NULL
;
1372 return VFR_RETURN_FATAL_ERROR
;
1377 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1378 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1379 *Size
= pDataType
->mTotalSize
;
1380 return VFR_RETURN_SUCCESS
;
1384 return VFR_RETURN_UNDEFINED
;
1388 CVfrVarDataTypeDB::GetDataFieldInfo (
1393 OUT BOOLEAN
&BitField
1396 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1397 UINT32 ArrayIdx
, Tmp
;
1398 SVfrDataType
*pType
= NULL
;
1399 SVfrDataField
*pField
= NULL
;
1403 Type
= EFI_IFR_TYPE_OTHER
;
1405 VarStrName
= VarStr
;
1407 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1408 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1410 BitField
= IsThisBitField (VarStrName
);
1413 // if it is not struct data type
1415 Type
= pType
->mType
;
1416 Size
= pType
->mTotalSize
;
1418 while (*VarStr
!= '\0') {
1419 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1420 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1421 pType
= pField
->mFieldType
;
1422 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
, pField
->mIsBitField
), VFR_RETURN_SUCCESS
);
1423 if (BitField
&& !pField
->mIsBitField
) {
1424 Offset
= (UINT16
) (Offset
+ Tmp
* 8);
1426 Offset
= (UINT16
) (Offset
+ Tmp
);
1428 Type
= GetFieldWidth (pField
);
1429 Size
= GetFieldSize (pField
, ArrayIdx
, BitField
);
1431 return VFR_RETURN_SUCCESS
;
1435 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1436 OUT CHAR8
***NameList
,
1437 OUT UINT32
*ListSize
1441 SVfrDataType
*pType
;
1443 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1444 return VFR_RETURN_FATAL_ERROR
;
1450 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1451 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1456 if (*ListSize
== 0) {
1457 return VFR_RETURN_SUCCESS
;
1460 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1462 return VFR_RETURN_OUT_FOR_RESOURCES
;
1465 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1466 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1467 (*NameList
)[Index
] = pType
->mTypeName
;
1470 return VFR_RETURN_SUCCESS
;
1474 CVfrVarDataTypeDB::IsTypeNameDefined (
1478 SVfrDataType
*pType
;
1480 if (TypeName
== NULL
) {
1484 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1485 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1494 CVfrVarDataTypeDB::Dump (
1498 SVfrDataType
*pTNode
;
1499 SVfrDataField
*pFNode
;
1501 fprintf (File
, "\n\n***************************************************************\n");
1502 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1503 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1504 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1505 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1506 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1507 if (pFNode
->mArrayNum
> 0) {
1508 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1509 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1511 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1512 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1515 fprintf (File
, "\t\t};\n");
1516 fprintf (File
, "---------------------------------------------------------------\n");
1518 fprintf (File
, "***************************************************************\n");
1521 #ifdef CVFR_VARDATATYPEDB_DEBUG
1523 CVfrVarDataTypeDB::ParserDB (
1527 SVfrDataType
*pTNode
;
1528 SVfrDataField
*pFNode
;
1530 printf ("***************************************************************\n");
1531 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1532 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1533 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1534 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1535 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1536 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1538 printf ("\t\t};\n");
1539 printf ("---------------------------------------------------------------\n");
1541 printf ("***************************************************************\n");
1545 SVfrVarStorageNode::SVfrVarStorageNode (
1547 IN CHAR8
*StoreName
,
1548 IN EFI_VARSTORE_ID VarStoreId
,
1549 IN EFI_STRING_ID VarName
,
1557 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1559 if (StoreName
!= NULL
) {
1560 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1561 strcpy (mVarStoreName
, StoreName
);
1563 mVarStoreName
= NULL
;
1566 mVarStoreId
= VarStoreId
;
1567 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1568 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1569 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1570 mAssignedFlag
= Flag
;
1573 SVfrVarStorageNode::SVfrVarStorageNode (
1575 IN CHAR8
*StoreName
,
1576 IN EFI_VARSTORE_ID VarStoreId
,
1577 IN SVfrDataType
*DataType
,
1578 IN BOOLEAN BitsVarstore
,
1585 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1587 if (StoreName
!= NULL
) {
1588 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1589 strcpy (mVarStoreName
, StoreName
);
1591 mVarStoreName
= NULL
;
1594 mVarStoreId
= VarStoreId
;
1596 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER_BITS
;
1598 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1600 mStorageInfo
.mDataType
= DataType
;
1601 mAssignedFlag
= Flag
;
1604 SVfrVarStorageNode::SVfrVarStorageNode (
1605 IN CHAR8
*StoreName
,
1606 IN EFI_VARSTORE_ID VarStoreId
1609 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1610 if (StoreName
!= NULL
) {
1611 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1612 strcpy (mVarStoreName
, StoreName
);
1614 mVarStoreName
= NULL
;
1617 mVarStoreId
= VarStoreId
;
1618 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1619 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1620 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1621 mAssignedFlag
= FALSE
;
1624 SVfrVarStorageNode::~SVfrVarStorageNode (
1628 if (mVarStoreName
!= NULL
) {
1629 delete[] mVarStoreName
;
1632 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1633 delete[] mStorageInfo
.mNameSpace
.mNameTable
;
1637 CVfrDataStorage::CVfrDataStorage (
1643 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1644 mFreeVarStoreIdBitMap
[Index
] = 0;
1647 // Question ID 0 is reserved.
1648 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1650 mBufferVarStoreList
= NULL
;
1651 mEfiVarStoreList
= NULL
;
1652 mNameVarStoreList
= NULL
;
1653 mCurrVarStorageNode
= NULL
;
1654 mNewVarStorageNode
= NULL
;
1655 mBufferFieldInfoListHead
= NULL
;
1656 mBufferFieldInfoListTail
= NULL
;
1659 CVfrDataStorage::~CVfrDataStorage (
1663 SVfrVarStorageNode
*pNode
;
1665 while (mBufferVarStoreList
!= NULL
) {
1666 pNode
= mBufferVarStoreList
;
1667 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1670 while (mEfiVarStoreList
!= NULL
) {
1671 pNode
= mEfiVarStoreList
;
1672 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1675 while (mNameVarStoreList
!= NULL
) {
1676 pNode
= mNameVarStoreList
;
1677 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1680 if (mNewVarStorageNode
!= NULL
) {
1681 delete mNewVarStorageNode
;
1686 CVfrDataStorage::GetFreeVarStoreId (
1687 EFI_VFR_VARSTORE_TYPE VarType
1690 UINT32 Index
, Mask
, Offset
;
1693 // Assign the different ID range for the different type VarStore to support Framework Vfr
1696 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1698 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1700 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1704 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1705 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1710 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1711 return EFI_VARSTORE_ID_INVALID
;
1714 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1715 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1716 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1717 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1721 return EFI_VARSTORE_ID_INVALID
;
1725 CVfrDataStorage::ChekVarStoreIdFree (
1726 IN EFI_VARSTORE_ID VarStoreId
1729 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1730 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1732 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1736 CVfrDataStorage::MarkVarStoreIdUsed (
1737 IN EFI_VARSTORE_ID VarStoreId
1740 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1741 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1743 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1747 CVfrDataStorage::MarkVarStoreIdUnused (
1748 IN EFI_VARSTORE_ID VarStoreId
1751 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1752 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1754 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1758 CVfrDataStorage::DeclareNameVarStoreBegin (
1759 IN CHAR8
*StoreName
,
1760 IN EFI_VARSTORE_ID VarStoreId
1763 SVfrVarStorageNode
*pNode
= NULL
;
1764 EFI_VARSTORE_ID TmpVarStoreId
;
1766 if (StoreName
== NULL
) {
1767 return VFR_RETURN_FATAL_ERROR
;
1770 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1771 return VFR_RETURN_REDEFINED
;
1774 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1775 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1777 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1778 return VFR_RETURN_VARSTOREID_REDEFINED
;
1780 MarkVarStoreIdUsed (VarStoreId
);
1783 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1784 return VFR_RETURN_UNDEFINED
;
1787 mNewVarStorageNode
= pNode
;
1789 return VFR_RETURN_SUCCESS
;
1793 CVfrDataStorage::NameTableAddItem (
1794 IN EFI_STRING_ID Item
1797 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1800 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1801 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1803 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1804 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1805 return VFR_RETURN_OUT_FOR_RESOURCES
;
1807 memcpy (NewTable
, OldTable
, TableSize
);
1808 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1811 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1812 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1814 return VFR_RETURN_SUCCESS
;
1818 CVfrDataStorage::DeclareNameVarStoreEnd (
1822 mNewVarStorageNode
->mGuid
= *Guid
;
1823 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1824 mNameVarStoreList
= mNewVarStorageNode
;
1826 mNewVarStorageNode
= NULL
;
1828 return VFR_RETURN_SUCCESS
;
1832 CVfrDataStorage::DeclareEfiVarStore (
1833 IN CHAR8
*StoreName
,
1835 IN EFI_STRING_ID NameStrId
,
1840 SVfrVarStorageNode
*pNode
;
1841 EFI_VARSTORE_ID VarStoreId
;
1843 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1844 return VFR_RETURN_FATAL_ERROR
;
1847 if (VarSize
> sizeof (UINT64
)) {
1848 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1851 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1852 return VFR_RETURN_REDEFINED
;
1855 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1856 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1857 return VFR_RETURN_OUT_FOR_RESOURCES
;
1860 pNode
->mNext
= mEfiVarStoreList
;
1861 mEfiVarStoreList
= pNode
;
1863 return VFR_RETURN_SUCCESS
;
1867 CVfrDataStorage::DeclareBufferVarStore (
1868 IN CHAR8
*StoreName
,
1870 IN CVfrVarDataTypeDB
*DataTypeDB
,
1872 IN EFI_VARSTORE_ID VarStoreId
,
1873 IN BOOLEAN IsBitVarStore
,
1877 SVfrVarStorageNode
*pNew
= NULL
;
1878 SVfrDataType
*pDataType
= NULL
;
1879 EFI_VARSTORE_ID TempVarStoreId
;
1881 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1882 return VFR_RETURN_FATAL_ERROR
;
1885 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1886 return VFR_RETURN_REDEFINED
;
1889 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1891 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1892 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1894 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1895 return VFR_RETURN_VARSTOREID_REDEFINED
;
1897 MarkVarStoreIdUsed (VarStoreId
);
1900 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, IsBitVarStore
, Flag
)) == NULL
) {
1901 return VFR_RETURN_OUT_FOR_RESOURCES
;
1904 pNew
->mNext
= mBufferVarStoreList
;
1905 mBufferVarStoreList
= pNew
;
1907 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1908 return VFR_RETURN_FATAL_ERROR
;
1911 return VFR_RETURN_SUCCESS
;
1915 CVfrDataStorage::GetVarStoreByDataType (
1916 IN CHAR8
*DataTypeName
,
1917 OUT SVfrVarStorageNode
**VarNode
,
1918 IN EFI_GUID
*VarGuid
1921 SVfrVarStorageNode
*pNode
;
1922 SVfrVarStorageNode
*MatchNode
;
1925 // Framework VFR uses Data type name as varstore name, so don't need check again.
1927 if (VfrCompatibleMode
) {
1928 return VFR_RETURN_UNDEFINED
;
1932 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1933 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1937 if ((VarGuid
!= NULL
)) {
1938 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1940 return VFR_RETURN_SUCCESS
;
1943 if (MatchNode
== NULL
) {
1947 // More than one varstores referred the same data structures.
1949 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1954 if (MatchNode
== NULL
) {
1955 return VFR_RETURN_UNDEFINED
;
1958 *VarNode
= MatchNode
;
1959 return VFR_RETURN_SUCCESS
;
1963 CVfrDataStorage::CheckGuidField (
1964 IN SVfrVarStorageNode
*pNode
,
1965 IN EFI_GUID
*StoreGuid
,
1966 IN BOOLEAN
*HasFoundOne
,
1967 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1970 if (StoreGuid
!= NULL
) {
1972 // If has guid info, compare the guid filed.
1974 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1976 // Both name and guid are same, this this varstore.
1978 mCurrVarStorageNode
= pNode
;
1979 *ReturnCode
= VFR_RETURN_SUCCESS
;
1984 // Not has Guid field, check whether this name is the only one.
1988 // The name has conflict, return name redefined.
1990 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1994 *HasFoundOne
= TRUE
;
1995 mCurrVarStorageNode
= pNode
;
2002 Base on the input store name and guid to find the varstore id.
2004 If both name and guid are inputed, base on the name and guid to
2005 found the varstore. If only name inputed, base on the name to
2006 found the varstore and go on to check whether more than one varstore
2007 has the same name. If only has found one varstore, return this
2008 varstore; if more than one varstore has same name, return varstore
2009 name redefined error. If no varstore found by varstore name, call
2010 function GetVarStoreByDataType and use inputed varstore name as
2011 data type name to search.
2014 CVfrDataStorage::GetVarStoreId (
2015 IN CHAR8
*StoreName
,
2016 OUT EFI_VARSTORE_ID
*VarStoreId
,
2017 IN EFI_GUID
*StoreGuid
2020 EFI_VFR_RETURN_CODE ReturnCode
;
2021 SVfrVarStorageNode
*pNode
;
2022 BOOLEAN HasFoundOne
= FALSE
;
2024 mCurrVarStorageNode
= NULL
;
2026 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2027 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2028 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2029 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2035 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2036 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2037 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2038 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2044 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2045 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2046 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2047 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2054 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2055 return VFR_RETURN_SUCCESS
;
2058 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
2061 // Assume that Data strucutre name is used as StoreName, and check again.
2063 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
2064 if (pNode
!= NULL
) {
2065 mCurrVarStorageNode
= pNode
;
2066 *VarStoreId
= pNode
->mVarStoreId
;
2073 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2074 IN EFI_VARSTORE_ID VarStoreId
,
2075 OUT CHAR8
**DataTypeName
2078 SVfrVarStorageNode
*pNode
;
2080 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2081 return VFR_RETURN_FATAL_ERROR
;
2084 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2085 if (pNode
->mVarStoreId
== VarStoreId
) {
2086 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
2087 return VFR_RETURN_SUCCESS
;
2091 return VFR_RETURN_UNDEFINED
;
2094 EFI_VFR_VARSTORE_TYPE
2095 CVfrDataStorage::GetVarStoreType (
2096 IN EFI_VARSTORE_ID VarStoreId
2099 SVfrVarStorageNode
*pNode
;
2100 EFI_VFR_VARSTORE_TYPE VarStoreType
;
2102 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
2104 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2105 return VarStoreType
;
2108 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2109 if (pNode
->mVarStoreId
== VarStoreId
) {
2110 VarStoreType
= pNode
->mVarStoreType
;
2111 return VarStoreType
;
2115 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2116 if (pNode
->mVarStoreId
== VarStoreId
) {
2117 VarStoreType
= pNode
->mVarStoreType
;
2118 return VarStoreType
;
2122 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2123 if (pNode
->mVarStoreId
== VarStoreId
) {
2124 VarStoreType
= pNode
->mVarStoreType
;
2125 return VarStoreType
;
2129 return VarStoreType
;
2133 CVfrDataStorage::GetVarStoreGuid (
2134 IN EFI_VARSTORE_ID VarStoreId
2137 SVfrVarStorageNode
*pNode
;
2142 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2146 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2147 if (pNode
->mVarStoreId
== VarStoreId
) {
2148 VarGuid
= &pNode
->mGuid
;
2153 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2154 if (pNode
->mVarStoreId
== VarStoreId
) {
2155 VarGuid
= &pNode
->mGuid
;
2160 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2161 if (pNode
->mVarStoreId
== VarStoreId
) {
2162 VarGuid
= &pNode
->mGuid
;
2171 CVfrDataStorage::GetVarStoreName (
2172 IN EFI_VARSTORE_ID VarStoreId
,
2173 OUT CHAR8
**VarStoreName
2176 SVfrVarStorageNode
*pNode
;
2178 if (VarStoreName
== NULL
) {
2179 return VFR_RETURN_FATAL_ERROR
;
2182 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2183 if (pNode
->mVarStoreId
== VarStoreId
) {
2184 *VarStoreName
= pNode
->mVarStoreName
;
2185 return VFR_RETURN_SUCCESS
;
2189 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2190 if (pNode
->mVarStoreId
== VarStoreId
) {
2191 *VarStoreName
= pNode
->mVarStoreName
;
2192 return VFR_RETURN_SUCCESS
;
2196 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2197 if (pNode
->mVarStoreId
== VarStoreId
) {
2198 *VarStoreName
= pNode
->mVarStoreName
;
2199 return VFR_RETURN_SUCCESS
;
2203 *VarStoreName
= NULL
;
2204 return VFR_RETURN_UNDEFINED
;
2208 CVfrDataStorage::GetEfiVarStoreInfo (
2209 IN OUT EFI_VARSTORE_INFO
*Info
2213 return VFR_RETURN_FATAL_ERROR
;
2216 if (mCurrVarStorageNode
== NULL
) {
2217 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
2220 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
2221 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
2222 switch (Info
->mVarTotalSize
) {
2224 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
2227 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
2230 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
2233 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2236 return VFR_RETURN_FATAL_ERROR
;
2239 return VFR_RETURN_SUCCESS
;
2243 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2244 IN EFI_VARSTORE_INFO
*Info
2247 BufferVarStoreFieldInfoNode
*pNew
;
2249 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2250 return VFR_RETURN_FATAL_ERROR
;
2253 if (mBufferFieldInfoListHead
== NULL
) {
2254 mBufferFieldInfoListHead
= pNew
;
2255 mBufferFieldInfoListTail
= pNew
;
2257 mBufferFieldInfoListTail
->mNext
= pNew
;
2258 mBufferFieldInfoListTail
= pNew
;
2261 return VFR_RETURN_SUCCESS
;
2265 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2266 IN OUT EFI_VARSTORE_INFO
*Info
2269 BufferVarStoreFieldInfoNode
*pNode
;
2271 pNode
= mBufferFieldInfoListHead
;
2272 while (pNode
!= NULL
) {
2273 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2274 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2275 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2276 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2277 return VFR_RETURN_SUCCESS
;
2279 pNode
= pNode
->mNext
;
2281 return VFR_RETURN_FATAL_ERROR
;
2285 CVfrDataStorage::GetNameVarStoreInfo (
2286 OUT EFI_VARSTORE_INFO
*Info
,
2291 return VFR_RETURN_FATAL_ERROR
;
2294 if (mCurrVarStorageNode
== NULL
) {
2295 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2299 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2301 if (VfrCompatibleMode
) {
2303 return VFR_RETURN_ERROR_ARRARY_NUM
;
2308 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2310 return VFR_RETURN_SUCCESS
;
2313 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2314 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2316 IN EFI_STRING_ID DefaultStoreNameId
,
2320 mObjBinAddr
= ObjBinAddr
;
2322 if (RefName
!= NULL
) {
2323 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2324 strcpy (mRefName
, RefName
);
2330 mDefaultId
= DefaultId
;
2331 mDefaultStoreNameId
= DefaultStoreNameId
;
2334 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2338 if (mRefName
!= NULL
) {
2343 CVfrDefaultStore::CVfrDefaultStore (
2347 mDefaultStoreList
= NULL
;
2350 CVfrDefaultStore::~CVfrDefaultStore (
2354 SVfrDefaultStoreNode
*pTmp
= NULL
;
2356 while (mDefaultStoreList
!= NULL
) {
2357 pTmp
= mDefaultStoreList
;
2358 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2364 CVfrDefaultStore::RegisterDefaultStore (
2365 IN CHAR8
*ObjBinAddr
,
2367 IN EFI_STRING_ID DefaultStoreNameId
,
2371 SVfrDefaultStoreNode
*pNode
= NULL
;
2373 if (RefName
== NULL
) {
2374 return VFR_RETURN_FATAL_ERROR
;
2377 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2378 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2379 return VFR_RETURN_REDEFINED
;
2383 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2384 return VFR_RETURN_OUT_FOR_RESOURCES
;
2387 pNode
->mNext
= mDefaultStoreList
;
2388 mDefaultStoreList
= pNode
;
2390 return VFR_RETURN_SUCCESS
;
2394 * assign new reference name or new default store name id only if
2395 * the original is invalid
2398 CVfrDefaultStore::ReRegisterDefaultStoreById (
2399 IN UINT16 DefaultId
,
2401 IN EFI_STRING_ID DefaultStoreNameId
2404 SVfrDefaultStoreNode
*pNode
= NULL
;
2406 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2407 if (pNode
->mDefaultId
== DefaultId
) {
2412 if (pNode
== NULL
) {
2413 return VFR_RETURN_UNDEFINED
;
2415 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2416 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2417 if (pNode
->mObjBinAddr
!= NULL
) {
2418 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2421 return VFR_RETURN_REDEFINED
;
2424 if (RefName
!= NULL
) {
2425 delete pNode
->mRefName
;
2426 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2427 if (pNode
->mRefName
!= NULL
) {
2428 strcpy (pNode
->mRefName
, RefName
);
2433 return VFR_RETURN_SUCCESS
;
2437 CVfrDefaultStore::DefaultIdRegistered (
2441 SVfrDefaultStoreNode
*pNode
= NULL
;
2443 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2444 if (pNode
->mDefaultId
== DefaultId
) {
2453 CVfrDefaultStore::GetDefaultId (
2455 OUT UINT16
*DefaultId
2458 SVfrDefaultStoreNode
*pTmp
= NULL
;
2460 if (DefaultId
== NULL
) {
2461 return VFR_RETURN_FATAL_ERROR
;
2464 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2465 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2466 *DefaultId
= pTmp
->mDefaultId
;
2467 return VFR_RETURN_SUCCESS
;
2471 return VFR_RETURN_UNDEFINED
;
2475 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2476 IN EFI_VARSTORE_ID DefaultId
,
2477 IN EFI_VARSTORE_INFO
&Info
,
2478 IN CHAR8
*VarStoreName
,
2479 IN EFI_GUID
*VarStoreGuid
,
2481 IN EFI_IFR_TYPE_VALUE Value
2484 SVfrDefaultStoreNode
*pNode
= NULL
;
2485 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2486 INTN Returnvalue
= 0;
2488 if (VarStoreName
== NULL
) {
2489 return VFR_RETURN_FATAL_ERROR
;
2492 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2493 if (pNode
->mDefaultId
== DefaultId
) {
2498 if (pNode
== NULL
) {
2499 return VFR_RETURN_UNDEFINED
;
2502 gCVfrBufferConfig
.Open ();
2504 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2505 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2506 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2511 gCVfrBufferConfig
.Close ();
2513 return VFR_RETURN_SUCCESS
;
2516 gCVfrBufferConfig
.Close ();
2517 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2520 SVfrRuleNode::SVfrRuleNode (
2525 if (RuleName
!= NULL
) {
2526 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2527 strcpy (mRuleName
, RuleName
);
2536 SVfrRuleNode::~SVfrRuleNode (
2540 if (mRuleName
!= NULL
) {
2545 CVfrRulesDB::CVfrRulesDB ()
2548 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2551 CVfrRulesDB::~CVfrRulesDB ()
2553 SVfrRuleNode
*pNode
;
2555 while(mRuleList
!= NULL
) {
2557 mRuleList
= mRuleList
->mNext
;
2563 CVfrRulesDB::RegisterRule (
2569 if (RuleName
== NULL
) {
2573 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2579 pNew
->mNext
= mRuleList
;
2584 CVfrRulesDB::GetRuleId (
2588 SVfrRuleNode
*pNode
;
2590 if (RuleName
== NULL
) {
2591 return EFI_RULE_ID_INVALID
;
2594 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2595 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2596 return pNode
->mRuleId
;
2600 return EFI_RULE_ID_INVALID
;
2603 CVfrRulesDB gCVfrRulesDB
;
2605 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2609 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2610 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2611 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2612 mVarType
= EFI_IFR_TYPE_OTHER
;
2617 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2618 IN EFI_VARSTORE_INFO
&Info
2621 mVarStoreId
= Info
.mVarStoreId
;
2622 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2623 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2624 mVarType
= Info
.mVarType
;
2625 mVarTotalSize
= Info
.mVarTotalSize
;
2626 mIsBitVar
= Info
.mIsBitVar
;
2630 EFI_VARSTORE_INFO::operator= (
2631 IN CONST EFI_VARSTORE_INFO
&Info
2634 if (this != &Info
) {
2635 mVarStoreId
= Info
.mVarStoreId
;
2636 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2637 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2638 mVarType
= Info
.mVarType
;
2639 mVarTotalSize
= Info
.mVarTotalSize
;
2640 mIsBitVar
= Info
.mIsBitVar
;
2647 EFI_VARSTORE_INFO::operator == (
2648 IN EFI_VARSTORE_INFO
*Info
2651 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2652 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2653 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2654 (mVarType
== Info
->mVarType
) &&
2655 (mVarTotalSize
== Info
->mVarTotalSize
) &&
2656 (mIsBitVar
== Info
->mIsBitVar
)) {
2663 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2664 IN EFI_VARSTORE_INFO
*Info
2667 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2668 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2669 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2670 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2674 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2676 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2677 mVarStoreInfo
.mVarTotalSize
= 0;
2678 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2679 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2683 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2686 CVfrQuestionDB::GetFreeQuestionId (
2690 UINT32 Index
, Mask
, Offset
;
2692 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2693 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2698 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2699 return EFI_QUESTION_ID_INVALID
;
2702 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2703 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2704 mFreeQIdBitMap
[Index
] |= Mask
;
2705 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2709 return EFI_QUESTION_ID_INVALID
;
2713 CVfrQuestionDB::ChekQuestionIdFree (
2714 IN EFI_QUESTION_ID QId
2717 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2718 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2720 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2724 CVfrQuestionDB::MarkQuestionIdUsed (
2725 IN EFI_QUESTION_ID QId
2728 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2729 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2731 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2735 CVfrQuestionDB::MarkQuestionIdUnused (
2736 IN EFI_QUESTION_ID QId
2739 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2740 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2742 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2745 SVfrQuestionNode::SVfrQuestionNode (
2753 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2756 mQtype
= QUESTION_NORMAL
;
2759 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2760 strcpy (mName
, "$DEFAULT");
2762 mName
= new CHAR8
[strlen (Name
) + 1];
2763 strcpy (mName
, Name
);
2766 if (VarIdStr
!= NULL
) {
2767 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2768 strcpy (mVarIdStr
, VarIdStr
);
2770 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2771 strcpy (mVarIdStr
, "$");
2775 SVfrQuestionNode::~SVfrQuestionNode (
2779 if (mName
!= NULL
) {
2783 if (mVarIdStr
!= NULL
) {
2788 CVfrQuestionDB::CVfrQuestionDB ()
2792 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2793 mFreeQIdBitMap
[Index
] = 0;
2796 // Question ID 0 is reserved.
2797 mFreeQIdBitMap
[0] = 0x80000000;
2798 mQuestionList
= NULL
;
2801 CVfrQuestionDB::~CVfrQuestionDB ()
2803 SVfrQuestionNode
*pNode
;
2805 while (mQuestionList
!= NULL
) {
2806 pNode
= mQuestionList
;
2807 mQuestionList
= mQuestionList
->mNext
;
2813 // Reset to init state
2816 CVfrQuestionDB::ResetInit(
2821 SVfrQuestionNode
*pNode
;
2823 while (mQuestionList
!= NULL
) {
2824 pNode
= mQuestionList
;
2825 mQuestionList
= mQuestionList
->mNext
;
2829 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2830 mFreeQIdBitMap
[Index
] = 0;
2833 // Question ID 0 is reserved.
2834 mFreeQIdBitMap
[0] = 0x80000000;
2835 mQuestionList
= NULL
;
2839 CVfrQuestionDB::PrintAllQuestion (
2843 SVfrQuestionNode
*pNode
= NULL
;
2845 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2846 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2851 CVfrQuestionDB::RegisterQuestion (
2854 IN OUT EFI_QUESTION_ID
&QuestionId
2857 SVfrQuestionNode
*pNode
= NULL
;
2859 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2860 return VFR_RETURN_REDEFINED
;
2863 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2864 return VFR_RETURN_OUT_FOR_RESOURCES
;
2867 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2868 QuestionId
= GetFreeQuestionId ();
2871 // For Framework Vfr, don't check question ID conflict.
2873 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2875 return VFR_RETURN_QUESTIONID_REDEFINED
;
2877 MarkQuestionIdUsed (QuestionId
);
2879 pNode
->mQuestionId
= QuestionId
;
2881 pNode
->mNext
= mQuestionList
;
2882 mQuestionList
= pNode
;
2884 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2886 return VFR_RETURN_SUCCESS
;
2890 CVfrQuestionDB::RegisterOldDateQuestion (
2891 IN CHAR8
*YearVarId
,
2892 IN CHAR8
*MonthVarId
,
2894 IN OUT EFI_QUESTION_ID
&QuestionId
2897 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2900 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2904 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2907 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2910 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2914 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2915 QuestionId
= GetFreeQuestionId ();
2917 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2920 MarkQuestionIdUsed (QuestionId
);
2923 pNode
[0]->mQuestionId
= QuestionId
;
2924 pNode
[1]->mQuestionId
= QuestionId
;
2925 pNode
[2]->mQuestionId
= QuestionId
;
2926 pNode
[0]->mQtype
= QUESTION_DATE
;
2927 pNode
[1]->mQtype
= QUESTION_DATE
;
2928 pNode
[2]->mQtype
= QUESTION_DATE
;
2929 pNode
[0]->mNext
= pNode
[1];
2930 pNode
[1]->mNext
= pNode
[2];
2931 pNode
[2]->mNext
= mQuestionList
;
2932 mQuestionList
= pNode
[0];
2934 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2935 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2936 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2941 for (Index
= 0; Index
< 3; Index
++) {
2942 if (pNode
[Index
] != NULL
) {
2943 delete pNode
[Index
];
2946 QuestionId
= EFI_QUESTION_ID_INVALID
;
2950 CVfrQuestionDB::RegisterNewDateQuestion (
2952 IN CHAR8
*BaseVarId
,
2953 IN OUT EFI_QUESTION_ID
&QuestionId
2956 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2958 CHAR8
*VarIdStr
[3] = {NULL
, };
2961 if (BaseVarId
== NULL
&& Name
== NULL
) {
2962 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2963 QuestionId
= GetFreeQuestionId ();
2965 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2968 MarkQuestionIdUsed (QuestionId
);
2973 if (BaseVarId
!= NULL
) {
2974 Len
= strlen (BaseVarId
);
2976 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2977 if (VarIdStr
[0] != NULL
) {
2978 strcpy (VarIdStr
[0], BaseVarId
);
2979 strcat (VarIdStr
[0], ".Year");
2981 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2982 if (VarIdStr
[1] != NULL
) {
2983 strcpy (VarIdStr
[1], BaseVarId
);
2984 strcat (VarIdStr
[1], ".Month");
2986 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2987 if (VarIdStr
[2] != NULL
) {
2988 strcpy (VarIdStr
[2], BaseVarId
);
2989 strcat (VarIdStr
[2], ".Day");
2992 Len
= strlen (Name
);
2994 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2995 if (VarIdStr
[0] != NULL
) {
2996 strcpy (VarIdStr
[0], Name
);
2997 strcat (VarIdStr
[0], ".Year");
2999 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
3000 if (VarIdStr
[1] != NULL
) {
3001 strcpy (VarIdStr
[1], Name
);
3002 strcat (VarIdStr
[1], ".Month");
3004 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
3005 if (VarIdStr
[2] != NULL
) {
3006 strcpy (VarIdStr
[2], Name
);
3007 strcat (VarIdStr
[2], ".Day");
3011 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
3014 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
3017 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
3021 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3022 QuestionId
= GetFreeQuestionId ();
3024 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3027 MarkQuestionIdUsed (QuestionId
);
3030 pNode
[0]->mQuestionId
= QuestionId
;
3031 pNode
[1]->mQuestionId
= QuestionId
;
3032 pNode
[2]->mQuestionId
= QuestionId
;
3033 pNode
[0]->mQtype
= QUESTION_DATE
;
3034 pNode
[1]->mQtype
= QUESTION_DATE
;
3035 pNode
[2]->mQtype
= QUESTION_DATE
;
3036 pNode
[0]->mNext
= pNode
[1];
3037 pNode
[1]->mNext
= pNode
[2];
3038 pNode
[2]->mNext
= mQuestionList
;
3039 mQuestionList
= pNode
[0];
3041 for (Index
= 0; Index
< 3; Index
++) {
3042 if (VarIdStr
[Index
] != NULL
) {
3043 delete VarIdStr
[Index
];
3047 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3048 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3049 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3054 for (Index
= 0; Index
< 3; Index
++) {
3055 if (pNode
[Index
] != NULL
) {
3056 delete pNode
[Index
];
3059 if (VarIdStr
[Index
] != NULL
) {
3060 delete VarIdStr
[Index
];
3066 CVfrQuestionDB::RegisterOldTimeQuestion (
3067 IN CHAR8
*HourVarId
,
3068 IN CHAR8
*MinuteVarId
,
3069 IN CHAR8
*SecondVarId
,
3070 IN OUT EFI_QUESTION_ID
&QuestionId
3073 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3076 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
3080 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
3083 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
3086 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
3090 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3091 QuestionId
= GetFreeQuestionId ();
3093 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3096 MarkQuestionIdUsed (QuestionId
);
3099 pNode
[0]->mQuestionId
= QuestionId
;
3100 pNode
[1]->mQuestionId
= QuestionId
;
3101 pNode
[2]->mQuestionId
= QuestionId
;
3102 pNode
[0]->mQtype
= QUESTION_TIME
;
3103 pNode
[1]->mQtype
= QUESTION_TIME
;
3104 pNode
[2]->mQtype
= QUESTION_TIME
;
3105 pNode
[0]->mNext
= pNode
[1];
3106 pNode
[1]->mNext
= pNode
[2];
3107 pNode
[2]->mNext
= mQuestionList
;
3108 mQuestionList
= pNode
[0];
3110 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3111 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3112 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3117 for (Index
= 0; Index
< 3; Index
++) {
3118 if (pNode
[Index
] != NULL
) {
3119 delete pNode
[Index
];
3122 QuestionId
= EFI_QUESTION_ID_INVALID
;
3126 CVfrQuestionDB::RegisterNewTimeQuestion (
3128 IN CHAR8
*BaseVarId
,
3129 IN OUT EFI_QUESTION_ID
&QuestionId
3132 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3134 CHAR8
*VarIdStr
[3] = {NULL
, };
3137 if (BaseVarId
== NULL
&& Name
== NULL
) {
3138 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3139 QuestionId
= GetFreeQuestionId ();
3141 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3144 MarkQuestionIdUsed (QuestionId
);
3149 if (BaseVarId
!= NULL
) {
3150 Len
= strlen (BaseVarId
);
3152 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3153 if (VarIdStr
[0] != NULL
) {
3154 strcpy (VarIdStr
[0], BaseVarId
);
3155 strcat (VarIdStr
[0], ".Hour");
3157 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3158 if (VarIdStr
[1] != NULL
) {
3159 strcpy (VarIdStr
[1], BaseVarId
);
3160 strcat (VarIdStr
[1], ".Minute");
3162 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3163 if (VarIdStr
[2] != NULL
) {
3164 strcpy (VarIdStr
[2], BaseVarId
);
3165 strcat (VarIdStr
[2], ".Second");
3168 Len
= strlen (Name
);
3170 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3171 if (VarIdStr
[0] != NULL
) {
3172 strcpy (VarIdStr
[0], Name
);
3173 strcat (VarIdStr
[0], ".Hour");
3175 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3176 if (VarIdStr
[1] != NULL
) {
3177 strcpy (VarIdStr
[1], Name
);
3178 strcat (VarIdStr
[1], ".Minute");
3180 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3181 if (VarIdStr
[2] != NULL
) {
3182 strcpy (VarIdStr
[2], Name
);
3183 strcat (VarIdStr
[2], ".Second");
3187 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
3190 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
3193 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
3197 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3198 QuestionId
= GetFreeQuestionId ();
3200 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3203 MarkQuestionIdUsed (QuestionId
);
3206 pNode
[0]->mQuestionId
= QuestionId
;
3207 pNode
[1]->mQuestionId
= QuestionId
;
3208 pNode
[2]->mQuestionId
= QuestionId
;
3209 pNode
[0]->mQtype
= QUESTION_TIME
;
3210 pNode
[1]->mQtype
= QUESTION_TIME
;
3211 pNode
[2]->mQtype
= QUESTION_TIME
;
3212 pNode
[0]->mNext
= pNode
[1];
3213 pNode
[1]->mNext
= pNode
[2];
3214 pNode
[2]->mNext
= mQuestionList
;
3215 mQuestionList
= pNode
[0];
3217 for (Index
= 0; Index
< 3; Index
++) {
3218 if (VarIdStr
[Index
] != NULL
) {
3219 delete VarIdStr
[Index
];
3223 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3224 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3225 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3230 for (Index
= 0; Index
< 3; Index
++) {
3231 if (pNode
[Index
] != NULL
) {
3232 delete pNode
[Index
];
3235 if (VarIdStr
[Index
] != NULL
) {
3236 delete VarIdStr
[Index
];
3242 CVfrQuestionDB::RegisterRefQuestion (
3244 IN CHAR8
*BaseVarId
,
3245 IN OUT EFI_QUESTION_ID
&QuestionId
3248 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3250 CHAR8
*VarIdStr
[4] = {NULL
, };
3253 if (BaseVarId
== NULL
&& Name
== NULL
) {
3257 if (BaseVarId
!= NULL
) {
3258 Len
= strlen (BaseVarId
);
3260 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3261 if (VarIdStr
[0] != NULL
) {
3262 strcpy (VarIdStr
[0], BaseVarId
);
3263 strcat (VarIdStr
[0], ".QuestionId");
3265 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3266 if (VarIdStr
[1] != NULL
) {
3267 strcpy (VarIdStr
[1], BaseVarId
);
3268 strcat (VarIdStr
[1], ".FormId");
3270 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3271 if (VarIdStr
[2] != NULL
) {
3272 strcpy (VarIdStr
[2], BaseVarId
);
3273 strcat (VarIdStr
[2], ".FormSetGuid");
3275 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3276 if (VarIdStr
[3] != NULL
) {
3277 strcpy (VarIdStr
[3], BaseVarId
);
3278 strcat (VarIdStr
[3], ".DevicePath");
3281 Len
= strlen (Name
);
3283 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3284 if (VarIdStr
[0] != NULL
) {
3285 strcpy (VarIdStr
[0], Name
);
3286 strcat (VarIdStr
[0], ".QuestionId");
3288 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3289 if (VarIdStr
[1] != NULL
) {
3290 strcpy (VarIdStr
[1], Name
);
3291 strcat (VarIdStr
[1], ".FormId");
3293 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3294 if (VarIdStr
[2] != NULL
) {
3295 strcpy (VarIdStr
[2], Name
);
3296 strcat (VarIdStr
[2], ".FormSetGuid");
3298 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3299 if (VarIdStr
[3] != NULL
) {
3300 strcpy (VarIdStr
[3], Name
);
3301 strcat (VarIdStr
[3], ".DevicePath");
3305 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3308 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3311 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3314 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3318 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3319 QuestionId
= GetFreeQuestionId ();
3321 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3324 MarkQuestionIdUsed (QuestionId
);
3327 pNode
[0]->mQuestionId
= QuestionId
;
3328 pNode
[1]->mQuestionId
= QuestionId
;
3329 pNode
[2]->mQuestionId
= QuestionId
;
3330 pNode
[3]->mQuestionId
= QuestionId
;
3331 pNode
[0]->mQtype
= QUESTION_REF
;
3332 pNode
[1]->mQtype
= QUESTION_REF
;
3333 pNode
[2]->mQtype
= QUESTION_REF
;
3334 pNode
[3]->mQtype
= QUESTION_REF
;
3335 pNode
[0]->mNext
= pNode
[1];
3336 pNode
[1]->mNext
= pNode
[2];
3337 pNode
[2]->mNext
= pNode
[3];
3338 pNode
[3]->mNext
= mQuestionList
;
3339 mQuestionList
= pNode
[0];
3341 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3342 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3343 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3344 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3349 for (Index
= 0; Index
< 4; Index
++) {
3350 if (pNode
[Index
] != NULL
) {
3351 delete pNode
[Index
];
3354 if (VarIdStr
[Index
] != NULL
) {
3355 delete VarIdStr
[Index
];
3361 CVfrQuestionDB::UpdateQuestionId (
3362 IN EFI_QUESTION_ID QId
,
3363 IN EFI_QUESTION_ID NewQId
3366 SVfrQuestionNode
*pNode
= NULL
;
3368 if (QId
== NewQId
) {
3370 return VFR_RETURN_SUCCESS
;
3374 // For Framework Vfr, don't check question ID conflict.
3376 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3377 return VFR_RETURN_REDEFINED
;
3380 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3381 if (pNode
->mQuestionId
== QId
) {
3386 if (pNode
== NULL
) {
3387 return VFR_RETURN_UNDEFINED
;
3390 MarkQuestionIdUnused (QId
);
3391 pNode
->mQuestionId
= NewQId
;
3392 MarkQuestionIdUsed (NewQId
);
3394 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3396 return VFR_RETURN_SUCCESS
;
3400 CVfrQuestionDB::GetQuestionId (
3403 OUT EFI_QUESTION_ID
&QuestionId
,
3404 OUT UINT32
&BitMask
,
3405 OUT EFI_QUESION_TYPE
*QType
3408 SVfrQuestionNode
*pNode
;
3410 QuestionId
= EFI_QUESTION_ID_INVALID
;
3411 BitMask
= 0x00000000;
3412 if (QType
!= NULL
) {
3413 *QType
= QUESTION_NORMAL
;
3416 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3420 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3422 if (strcmp (pNode
->mName
, Name
) != 0) {
3427 if (VarIdStr
!= NULL
) {
3428 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3433 QuestionId
= pNode
->mQuestionId
;
3434 BitMask
= pNode
->mBitMask
;
3435 if (QType
!= NULL
) {
3436 *QType
= pNode
->mQtype
;
3445 CVfrQuestionDB::FindQuestion (
3446 IN EFI_QUESTION_ID QuestionId
3449 SVfrQuestionNode
*pNode
;
3451 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3452 return VFR_RETURN_INVALID_PARAMETER
;
3455 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3456 if (pNode
->mQuestionId
== QuestionId
) {
3457 return VFR_RETURN_SUCCESS
;
3461 return VFR_RETURN_UNDEFINED
;
3465 CVfrQuestionDB::FindQuestion (
3469 SVfrQuestionNode
*pNode
;
3472 return VFR_RETURN_FATAL_ERROR
;
3475 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3476 if (strcmp (pNode
->mName
, Name
) == 0) {
3477 return VFR_RETURN_SUCCESS
;
3481 return VFR_RETURN_UNDEFINED
;
3484 CVfrStringDB::CVfrStringDB ()
3486 mStringFileName
= NULL
;
3489 CVfrStringDB::~CVfrStringDB ()
3491 if (mStringFileName
!= NULL
) {
3492 delete[] mStringFileName
;
3494 mStringFileName
= NULL
;
3499 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3503 if (StringFileName
== NULL
) {
3507 if (mStringFileName
!= NULL
) {
3508 delete[] mStringFileName
;
3511 FileLen
= strlen (StringFileName
) + 1;
3512 mStringFileName
= new CHAR8
[FileLen
];
3513 if (mStringFileName
== NULL
) {
3517 strcpy (mStringFileName
, StringFileName
);
3518 mStringFileName
[FileLen
- 1] = '\0';
3523 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3524 from a set of supported languages.
3526 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3527 contains a set of language codes.
3528 @param[in] Language A variable that contains pointers to Null-terminated
3529 ASCII strings that contain one language codes.
3531 @retval FALSE The best matching language could not be found in SupportedLanguages.
3532 @retval TRUE The best matching language could be found in SupportedLanguages.
3536 CVfrStringDB::GetBestLanguage (
3537 IN CONST CHAR8
*SupportedLanguages
,
3541 UINTN CompareLength
;
3542 UINTN LanguageLength
;
3543 CONST CHAR8
*Supported
;
3545 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3550 // Determine the length of the first RFC 4646 language code in Language
3552 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3555 // Trim back the length of Language used until it is empty
3557 while (LanguageLength
> 0) {
3559 // Loop through all language codes in SupportedLanguages
3561 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3563 // Skip ';' characters in Supported
3565 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3567 // Determine the length of the next language code in Supported
3569 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3571 // If Language is longer than the Supported, then skip to the next language
3573 if (LanguageLength
> CompareLength
) {
3578 // See if the first LanguageLength characters in Supported match Language
3580 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3586 // Trim Language from the right to the next '-' character
3588 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3592 // No matches were found
3599 CVfrStringDB::GetVarStoreNameFormStringId (
3600 IN EFI_STRING_ID StringId
3603 FILE *pInFile
= NULL
;
3608 CHAR16
*UnicodeString
;
3609 CHAR8
*VarStoreName
= NULL
;
3613 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3615 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3617 if (mStringFileName
== NULL
) {
3621 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3628 fseek (pInFile
, 0, SEEK_END
);
3629 Length
= ftell (pInFile
);
3630 fseek (pInFile
, 0, SEEK_SET
);
3635 StringPtr
= new UINT8
[Length
];
3636 if (StringPtr
== NULL
) {
3640 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3643 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3645 // Check the String package.
3647 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3653 // Search the language, get best language base on RFC 4647 matching algorithm.
3655 Current
= StringPtr
;
3656 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3657 Current
+= PkgHeader
->Header
.Length
;
3658 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3660 // If can't find string package base on language, just return the first string package.
3662 if (Current
- StringPtr
>= Length
) {
3663 Current
= StringPtr
;
3664 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3669 Current
+= PkgHeader
->HdrSize
;
3671 // Find the string block according the stringId.
3673 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3674 if (Status
!= EFI_SUCCESS
) {
3680 // Get varstore name according the string type.
3682 switch (BlockType
) {
3683 case EFI_HII_SIBT_STRING_SCSU
:
3684 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3685 case EFI_HII_SIBT_STRINGS_SCSU
:
3686 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3687 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3688 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3689 strcpy (VarStoreName
, StringName
);
3691 case EFI_HII_SIBT_STRING_UCS2
:
3692 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3693 case EFI_HII_SIBT_STRINGS_UCS2
:
3694 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3695 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3696 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3697 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3698 VarStoreName
= DestTmp
;
3699 while (*UnicodeString
!= '\0') {
3700 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3710 return VarStoreName
;
3714 CVfrStringDB::FindStringBlock (
3715 IN UINT8
*StringData
,
3716 IN EFI_STRING_ID StringId
,
3717 OUT UINT32
*StringTextOffset
,
3718 OUT UINT8
*BlockType
3722 EFI_STRING_ID CurrentStringId
;
3725 UINT8
*StringTextPtr
;
3730 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3734 CurrentStringId
= 1;
3737 // Parse the string blocks to get the string text and font.
3739 BlockHdr
= StringData
;
3742 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3743 switch (*BlockHdr
) {
3744 case EFI_HII_SIBT_STRING_SCSU
:
3745 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3746 StringTextPtr
= BlockHdr
+ Offset
;
3747 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3751 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3752 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3753 StringTextPtr
= BlockHdr
+ Offset
;
3754 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3758 case EFI_HII_SIBT_STRINGS_SCSU
:
3759 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3760 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3761 BlockSize
+= StringTextPtr
- BlockHdr
;
3763 for (Index
= 0; Index
< StringCount
; Index
++) {
3764 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3765 if (CurrentStringId
== StringId
) {
3766 *BlockType
= *BlockHdr
;
3767 *StringTextOffset
= StringTextPtr
- StringData
;
3770 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3775 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3778 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3781 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3782 BlockSize
+= StringTextPtr
- BlockHdr
;
3784 for (Index
= 0; Index
< StringCount
; Index
++) {
3785 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3786 if (CurrentStringId
== StringId
) {
3787 *BlockType
= *BlockHdr
;
3788 *StringTextOffset
= StringTextPtr
- StringData
;
3791 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3796 case EFI_HII_SIBT_STRING_UCS2
:
3797 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3798 StringTextPtr
= BlockHdr
+ Offset
;
3800 // Use StringSize to store the size of the specified string, including the NULL
3803 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3804 BlockSize
+= Offset
+ StringSize
;
3808 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3809 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3810 StringTextPtr
= BlockHdr
+ Offset
;
3812 // Use StrSize to store the size of the specified string, including the NULL
3815 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3816 BlockSize
+= Offset
+ StringSize
;
3820 case EFI_HII_SIBT_STRINGS_UCS2
:
3821 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3822 StringTextPtr
= BlockHdr
+ Offset
;
3823 BlockSize
+= Offset
;
3824 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3825 for (Index
= 0; Index
< StringCount
; Index
++) {
3826 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3827 BlockSize
+= StringSize
;
3828 if (CurrentStringId
== StringId
) {
3829 *BlockType
= *BlockHdr
;
3830 *StringTextOffset
= StringTextPtr
- StringData
;
3833 StringTextPtr
= StringTextPtr
+ StringSize
;
3838 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3839 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3840 StringTextPtr
= BlockHdr
+ Offset
;
3841 BlockSize
+= Offset
;
3844 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3847 for (Index
= 0; Index
< StringCount
; Index
++) {
3848 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3849 BlockSize
+= StringSize
;
3850 if (CurrentStringId
== StringId
) {
3851 *BlockType
= *BlockHdr
;
3852 *StringTextOffset
= StringTextPtr
- StringData
;
3855 StringTextPtr
= StringTextPtr
+ StringSize
;
3860 case EFI_HII_SIBT_DUPLICATE
:
3861 if (CurrentStringId
== StringId
) {
3863 // Incoming StringId is an id of a duplicate string block.
3864 // Update the StringId to be the previous string block.
3865 // Go back to the header of string block to search.
3869 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3870 sizeof (EFI_STRING_ID
)
3872 CurrentStringId
= 1;
3875 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3880 case EFI_HII_SIBT_SKIP1
:
3881 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3882 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3883 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3886 case EFI_HII_SIBT_SKIP2
:
3887 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3888 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3889 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3892 case EFI_HII_SIBT_EXT1
:
3895 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3898 BlockSize
+= Length8
;
3901 case EFI_HII_SIBT_EXT2
:
3902 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3903 BlockSize
+= Ext2
.Length
;
3906 case EFI_HII_SIBT_EXT4
:
3909 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3913 BlockSize
+= Length32
;
3920 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3921 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3922 *BlockType
= *BlockHdr
;
3924 if (StringId
== CurrentStringId
- 1) {
3926 // if only one skip item, return EFI_NOT_FOUND.
3928 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3929 return EFI_NOT_FOUND
;
3935 if (StringId
< CurrentStringId
- 1) {
3936 return EFI_NOT_FOUND
;
3939 BlockHdr
= StringData
+ BlockSize
;
3942 return EFI_NOT_FOUND
;
3946 CVfrStringDB::GetUnicodeStringTextSize (
3953 StringSize
= sizeof (CHAR16
);
3954 StringPtr
= (UINT16
*)StringSrc
;
3955 while (*StringPtr
++ != L
'\0') {
3956 StringSize
+= sizeof (CHAR16
);
3962 BOOLEAN VfrCompatibleMode
= FALSE
;
3964 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3965 CVfrDefaultStore gCVfrDefaultStore
;
3966 CVfrDataStorage gCVfrDataStorage
;