3 Vfr common library functions.
5 Copyright (c) 2004 - 2017, 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
;
962 InternalTypesListInit ();
965 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
970 SVfrDataField
*pField
;
971 SVfrPackStackNode
*pPack
;
973 if (mNewDataType
!= NULL
) {
977 while (mDataTypeList
!= NULL
) {
978 pType
= mDataTypeList
;
979 mDataTypeList
= mDataTypeList
->mNext
;
980 while(pType
->mMembers
!= NULL
) {
981 pField
= pType
->mMembers
;
982 pType
->mMembers
= pType
->mMembers
->mNext
;
988 while (mPackStack
!= NULL
) {
990 mPackStack
= mPackStack
->mNext
;
996 CVfrVarDataTypeDB::Pack (
999 IN CHAR8
*Identifier
,
1004 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
1006 if (Action
& VFR_PACK_SHOW
) {
1007 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
1008 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
1011 if (Action
& VFR_PACK_PUSH
) {
1012 SVfrPackStackNode
*pNew
= NULL
;
1014 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
1015 return VFR_RETURN_FATAL_ERROR
;
1017 pNew
->mNext
= mPackStack
;
1021 if (Action
& VFR_PACK_POP
) {
1022 SVfrPackStackNode
*pNode
= NULL
;
1024 if (mPackStack
== NULL
) {
1025 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
1028 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1029 if (pNode
->Match (Identifier
) == TRUE
) {
1030 mPackAlign
= pNode
->mNumber
;
1031 mPackStack
= pNode
->mNext
;
1036 if (Action
& VFR_PACK_ASSIGN
) {
1037 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
1038 if ((PackAlign
== 0) || (PackAlign
> 16)) {
1039 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
1041 mPackAlign
= PackAlign
;
1045 return VFR_RETURN_SUCCESS
;
1049 CVfrVarDataTypeDB::DeclareDataTypeBegin (
1053 SVfrDataType
*pNewType
= NULL
;
1055 pNewType
= new SVfrDataType
;
1056 pNewType
->mTypeName
[0] = '\0';
1057 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
1058 pNewType
->mAlign
= DEFAULT_ALIGN
;
1059 pNewType
->mTotalSize
= 0;
1060 pNewType
->mMembers
= NULL
;
1061 pNewType
->mNext
= NULL
;
1062 pNewType
->mHasBitField
= FALSE
;
1064 mNewDataType
= pNewType
;
1068 CVfrVarDataTypeDB::SetNewTypeName (
1072 SVfrDataType
*pType
;
1074 if (mNewDataType
== NULL
) {
1075 return VFR_RETURN_ERROR_SKIPED
;
1077 if (TypeName
== NULL
) {
1078 return VFR_RETURN_FATAL_ERROR
;
1080 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
1081 return VFR_RETURN_INVALID_PARAMETER
;
1084 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1085 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1086 return VFR_RETURN_REDEFINED
;
1090 strncpy(mNewDataType
->mTypeName
, TypeName
, MAX_NAME_LEN
- 1);
1091 mNewDataType
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
1092 return VFR_RETURN_SUCCESS
;
1096 Record the bit field info in the data type.
1098 @param FieldName Point to the field name.
1099 @param TypeName Point to the type name.
1100 @param Width The bit width.
1101 @param FieldInUnion The filed is in Union type or Structure type.
1105 CVfrVarDataTypeDB::DataTypeAddBitField (
1106 IN CHAR8
*FieldName
,
1109 IN BOOLEAN FieldInUnion
1112 SVfrDataField
*pNewField
= NULL
;
1113 SVfrDataType
*pFieldType
= NULL
;
1114 SVfrDataField
*pTmp
;
1116 UINT32 MaxDataTypeSize
;
1117 BOOLEAN UpdateTotalSize
;
1119 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1121 if (Width
> MAX_BIT_WIDTH
) {
1122 return VFR_RETURN_BIT_WIDTH_ERROR
;
1125 if (Width
> pFieldType
->mTotalSize
* 8) {
1126 return VFR_RETURN_BIT_WIDTH_ERROR
;
1129 if (FieldName
!= NULL
&& strlen (FieldName
) >= MAX_NAME_LEN
) {
1130 return VFR_RETURN_INVALID_PARAMETER
;
1133 if (Width
== 0 && FieldName
!= NULL
) {
1134 return VFR_RETURN_INVALID_PARAMETER
;
1137 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1138 if (FieldName
!= NULL
&& strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1139 return VFR_RETURN_REDEFINED
;
1143 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1144 UpdateTotalSize
= FALSE
;
1146 if ((pNewField
= new SVfrDataField
) == NULL
) {
1147 return VFR_RETURN_OUT_FOR_RESOURCES
;
1150 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1151 if (FieldName
!= NULL
) {
1152 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1153 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1155 pNewField
->mFieldType
= pFieldType
;
1156 pNewField
->mIsBitField
= TRUE
;
1157 pNewField
->mBitWidth
= Width
;
1158 pNewField
->mArrayNum
= 0;
1159 pNewField
->mBitOffset
= 0;
1160 pNewField
->mOffset
= 0;
1162 if (mNewDataType
->mMembers
== NULL
) {
1163 mNewDataType
->mMembers
= pNewField
;
1164 pNewField
->mNext
= NULL
;
1166 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1168 pTmp
->mNext
= pNewField
;
1169 pNewField
->mNext
= NULL
;
1173 pNewField
->mOffset
= 0;
1174 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1175 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1179 // Check whether the bit fileds can be contained within one FieldType.
1181 if (pTmp
!= NULL
&& pTmp
->mIsBitField
&& strcmp (pTmp
->mFieldType
->mTypeName
, pNewField
->mFieldType
->mTypeName
) == 0 &&
1182 (pTmp
->mBitOffset
- pTmp
->mOffset
* 8) + pTmp
->mBitWidth
+ pNewField
->mBitWidth
<= pNewField
->mFieldType
->mTotalSize
* 8) {
1183 pNewField
->mBitOffset
= pTmp
->mBitOffset
+ pTmp
->mBitWidth
;
1184 pNewField
->mOffset
= pTmp
->mOffset
;
1186 // If BitWidth=0,used to force alignment at the next word boundary.
1187 // So make this bit field occupy the remaing bit width of current field type.
1189 if (pNewField
->mBitWidth
== 0) {
1190 pNewField
->mBitWidth
= pNewField
->mFieldType
->mTotalSize
* 8 - (pNewField
->mBitOffset
- pTmp
->mOffset
* 8);
1194 // The bit filed start a new memory
1196 pNewField
->mBitOffset
= mNewDataType
->mTotalSize
* 8;
1197 UpdateTotalSize
= TRUE
;
1201 if (UpdateTotalSize
){
1202 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1203 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1205 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1207 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
);
1210 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1211 mNewDataType
->mHasBitField
= TRUE
;
1212 return VFR_RETURN_SUCCESS
;
1216 CVfrVarDataTypeDB::DataTypeAddField (
1217 IN CHAR8
*FieldName
,
1220 IN BOOLEAN FieldInUnion
1223 SVfrDataField
*pNewField
= NULL
;
1224 SVfrDataType
*pFieldType
= NULL
;
1225 SVfrDataField
*pTmp
;
1227 UINT32 MaxDataTypeSize
;
1229 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1230 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1232 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1233 return VFR_RETURN_INVALID_PARAMETER
;
1236 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1237 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1238 return VFR_RETURN_REDEFINED
;
1242 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1244 if ((pNewField
= new SVfrDataField
) == NULL
) {
1245 return VFR_RETURN_OUT_FOR_RESOURCES
;
1247 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1248 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1249 pNewField
->mFieldType
= pFieldType
;
1250 pNewField
->mArrayNum
= ArrayNum
;
1251 pNewField
->mIsBitField
= FALSE
;
1252 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1253 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1255 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1257 if (mNewDataType
->mMembers
== NULL
) {
1258 mNewDataType
->mMembers
= pNewField
;
1259 pNewField
->mNext
= NULL
;
1261 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1263 pTmp
->mNext
= pNewField
;
1264 pNewField
->mNext
= NULL
;
1267 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1270 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1271 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1273 pNewField
->mOffset
= 0;
1275 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1278 return VFR_RETURN_SUCCESS
;
1282 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1286 if (mNewDataType
->mTypeName
[0] == '\0') {
1290 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1291 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1294 RegisterNewType (mNewDataType
);
1295 if (mFirstNewDataTypeName
== NULL
) {
1296 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1299 mNewDataType
= NULL
;
1303 CVfrVarDataTypeDB::GetDataType (
1305 OUT SVfrDataType
**DataType
1308 SVfrDataType
*pDataType
= NULL
;
1310 if (TypeName
== NULL
) {
1311 return VFR_RETURN_ERROR_SKIPED
;
1314 if (DataType
== NULL
) {
1315 return VFR_RETURN_FATAL_ERROR
;
1320 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1321 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1322 *DataType
= pDataType
;
1323 return VFR_RETURN_SUCCESS
;
1327 return VFR_RETURN_UNDEFINED
;
1331 CVfrVarDataTypeDB::GetDataTypeSize (
1336 SVfrDataType
*pDataType
= NULL
;
1339 return VFR_RETURN_FATAL_ERROR
;
1343 DataType
= DataType
& 0x0F;
1346 // For user defined data type, the size can't be got by this function.
1348 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1349 return VFR_RETURN_SUCCESS
;
1352 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1353 if (DataType
== pDataType
->mType
) {
1354 *Size
= pDataType
->mTotalSize
;
1355 return VFR_RETURN_SUCCESS
;
1359 return VFR_RETURN_UNDEFINED
;
1363 CVfrVarDataTypeDB::GetDataTypeSize (
1368 SVfrDataType
*pDataType
= NULL
;
1371 return VFR_RETURN_FATAL_ERROR
;
1376 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1377 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1378 *Size
= pDataType
->mTotalSize
;
1379 return VFR_RETURN_SUCCESS
;
1383 return VFR_RETURN_UNDEFINED
;
1387 CVfrVarDataTypeDB::GetDataFieldInfo (
1392 OUT BOOLEAN
&BitField
1395 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1396 UINT32 ArrayIdx
, Tmp
;
1397 SVfrDataType
*pType
= NULL
;
1398 SVfrDataField
*pField
= NULL
;
1402 Type
= EFI_IFR_TYPE_OTHER
;
1404 VarStrName
= VarStr
;
1406 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1407 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1409 BitField
= IsThisBitField (VarStrName
);
1412 // if it is not struct data type
1414 Type
= pType
->mType
;
1415 Size
= pType
->mTotalSize
;
1417 while (*VarStr
!= '\0') {
1418 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1419 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1420 pType
= pField
->mFieldType
;
1421 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
, pField
->mIsBitField
), VFR_RETURN_SUCCESS
);
1422 if (BitField
&& !pField
->mIsBitField
) {
1423 Offset
= (UINT16
) (Offset
+ Tmp
* 8);
1425 Offset
= (UINT16
) (Offset
+ Tmp
);
1427 Type
= GetFieldWidth (pField
);
1428 Size
= GetFieldSize (pField
, ArrayIdx
, BitField
);
1430 return VFR_RETURN_SUCCESS
;
1434 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1435 OUT CHAR8
***NameList
,
1436 OUT UINT32
*ListSize
1440 SVfrDataType
*pType
;
1442 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1443 return VFR_RETURN_FATAL_ERROR
;
1449 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1450 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1455 if (*ListSize
== 0) {
1456 return VFR_RETURN_SUCCESS
;
1459 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1461 return VFR_RETURN_OUT_FOR_RESOURCES
;
1464 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1465 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1466 (*NameList
)[Index
] = pType
->mTypeName
;
1469 return VFR_RETURN_SUCCESS
;
1473 CVfrVarDataTypeDB::IsTypeNameDefined (
1477 SVfrDataType
*pType
;
1479 if (TypeName
== NULL
) {
1483 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1484 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1493 CVfrVarDataTypeDB::Dump (
1497 SVfrDataType
*pTNode
;
1498 SVfrDataField
*pFNode
;
1500 fprintf (File
, "\n\n***************************************************************\n");
1501 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1502 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1503 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1504 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1505 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1506 if (pFNode
->mArrayNum
> 0) {
1507 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1508 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1510 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1511 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1514 fprintf (File
, "\t\t};\n");
1515 fprintf (File
, "---------------------------------------------------------------\n");
1517 fprintf (File
, "***************************************************************\n");
1520 #ifdef CVFR_VARDATATYPEDB_DEBUG
1522 CVfrVarDataTypeDB::ParserDB (
1526 SVfrDataType
*pTNode
;
1527 SVfrDataField
*pFNode
;
1529 printf ("***************************************************************\n");
1530 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1531 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1532 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1533 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1534 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1535 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1537 printf ("\t\t};\n");
1538 printf ("---------------------------------------------------------------\n");
1540 printf ("***************************************************************\n");
1544 SVfrVarStorageNode::SVfrVarStorageNode (
1546 IN CHAR8
*StoreName
,
1547 IN EFI_VARSTORE_ID VarStoreId
,
1548 IN EFI_STRING_ID VarName
,
1556 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1558 if (StoreName
!= NULL
) {
1559 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1560 strcpy (mVarStoreName
, StoreName
);
1562 mVarStoreName
= NULL
;
1565 mVarStoreId
= VarStoreId
;
1566 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1567 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1568 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1569 mAssignedFlag
= Flag
;
1572 SVfrVarStorageNode::SVfrVarStorageNode (
1574 IN CHAR8
*StoreName
,
1575 IN EFI_VARSTORE_ID VarStoreId
,
1576 IN SVfrDataType
*DataType
,
1577 IN BOOLEAN BitsVarstore
,
1584 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1586 if (StoreName
!= NULL
) {
1587 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1588 strcpy (mVarStoreName
, StoreName
);
1590 mVarStoreName
= NULL
;
1593 mVarStoreId
= VarStoreId
;
1595 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER_BITS
;
1597 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1599 mStorageInfo
.mDataType
= DataType
;
1600 mAssignedFlag
= Flag
;
1603 SVfrVarStorageNode::SVfrVarStorageNode (
1604 IN CHAR8
*StoreName
,
1605 IN EFI_VARSTORE_ID VarStoreId
1608 if (StoreName
!= NULL
) {
1609 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1610 strcpy (mVarStoreName
, StoreName
);
1612 mVarStoreName
= NULL
;
1615 mVarStoreId
= VarStoreId
;
1616 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1617 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1618 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1621 SVfrVarStorageNode::~SVfrVarStorageNode (
1625 if (mVarStoreName
!= NULL
) {
1626 delete[] mVarStoreName
;
1629 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1630 delete mStorageInfo
.mNameSpace
.mNameTable
;
1634 CVfrDataStorage::CVfrDataStorage (
1640 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1641 mFreeVarStoreIdBitMap
[Index
] = 0;
1644 // Question ID 0 is reserved.
1645 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1647 mBufferVarStoreList
= NULL
;
1648 mEfiVarStoreList
= NULL
;
1649 mNameVarStoreList
= NULL
;
1650 mCurrVarStorageNode
= NULL
;
1651 mNewVarStorageNode
= NULL
;
1652 mBufferFieldInfoListHead
= NULL
;
1653 mBufferFieldInfoListTail
= NULL
;
1656 CVfrDataStorage::~CVfrDataStorage (
1660 SVfrVarStorageNode
*pNode
;
1662 while (mBufferVarStoreList
!= NULL
) {
1663 pNode
= mBufferVarStoreList
;
1664 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1667 while (mEfiVarStoreList
!= NULL
) {
1668 pNode
= mEfiVarStoreList
;
1669 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1672 while (mNameVarStoreList
!= NULL
) {
1673 pNode
= mNameVarStoreList
;
1674 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1677 if (mNewVarStorageNode
!= NULL
) {
1678 delete mNewVarStorageNode
;
1683 CVfrDataStorage::GetFreeVarStoreId (
1684 EFI_VFR_VARSTORE_TYPE VarType
1687 UINT32 Index
, Mask
, Offset
;
1690 // Assign the different ID range for the different type VarStore to support Framework Vfr
1693 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1695 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1697 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1701 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1702 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1707 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1708 return EFI_VARSTORE_ID_INVALID
;
1711 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1712 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1713 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1714 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1718 return EFI_VARSTORE_ID_INVALID
;
1722 CVfrDataStorage::ChekVarStoreIdFree (
1723 IN EFI_VARSTORE_ID VarStoreId
1726 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1727 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1729 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1733 CVfrDataStorage::MarkVarStoreIdUsed (
1734 IN EFI_VARSTORE_ID VarStoreId
1737 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1738 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1740 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1744 CVfrDataStorage::MarkVarStoreIdUnused (
1745 IN EFI_VARSTORE_ID VarStoreId
1748 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1749 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1751 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1755 CVfrDataStorage::DeclareNameVarStoreBegin (
1756 IN CHAR8
*StoreName
,
1757 IN EFI_VARSTORE_ID VarStoreId
1760 SVfrVarStorageNode
*pNode
= NULL
;
1761 EFI_VARSTORE_ID TmpVarStoreId
;
1763 if (StoreName
== NULL
) {
1764 return VFR_RETURN_FATAL_ERROR
;
1767 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1768 return VFR_RETURN_REDEFINED
;
1771 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1772 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1774 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1775 return VFR_RETURN_VARSTOREID_REDEFINED
;
1777 MarkVarStoreIdUsed (VarStoreId
);
1780 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1781 return VFR_RETURN_UNDEFINED
;
1784 mNewVarStorageNode
= pNode
;
1786 return VFR_RETURN_SUCCESS
;
1790 CVfrDataStorage::NameTableAddItem (
1791 IN EFI_STRING_ID Item
1794 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1797 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1798 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1800 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1801 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1802 return VFR_RETURN_OUT_FOR_RESOURCES
;
1804 memcpy (NewTable
, OldTable
, TableSize
);
1805 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1808 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1809 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1811 return VFR_RETURN_SUCCESS
;
1815 CVfrDataStorage::DeclareNameVarStoreEnd (
1819 mNewVarStorageNode
->mGuid
= *Guid
;
1820 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1821 mNameVarStoreList
= mNewVarStorageNode
;
1823 mNewVarStorageNode
= NULL
;
1825 return VFR_RETURN_SUCCESS
;
1829 CVfrDataStorage::DeclareEfiVarStore (
1830 IN CHAR8
*StoreName
,
1832 IN EFI_STRING_ID NameStrId
,
1837 SVfrVarStorageNode
*pNode
;
1838 EFI_VARSTORE_ID VarStoreId
;
1840 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1841 return VFR_RETURN_FATAL_ERROR
;
1844 if (VarSize
> sizeof (UINT64
)) {
1845 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1848 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1849 return VFR_RETURN_REDEFINED
;
1852 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1853 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1854 return VFR_RETURN_OUT_FOR_RESOURCES
;
1857 pNode
->mNext
= mEfiVarStoreList
;
1858 mEfiVarStoreList
= pNode
;
1860 return VFR_RETURN_SUCCESS
;
1864 CVfrDataStorage::DeclareBufferVarStore (
1865 IN CHAR8
*StoreName
,
1867 IN CVfrVarDataTypeDB
*DataTypeDB
,
1869 IN EFI_VARSTORE_ID VarStoreId
,
1870 IN BOOLEAN IsBitVarStore
,
1874 SVfrVarStorageNode
*pNew
= NULL
;
1875 SVfrDataType
*pDataType
= NULL
;
1876 EFI_VARSTORE_ID TempVarStoreId
;
1878 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1879 return VFR_RETURN_FATAL_ERROR
;
1882 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1883 return VFR_RETURN_REDEFINED
;
1886 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1888 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1889 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1891 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1892 return VFR_RETURN_VARSTOREID_REDEFINED
;
1894 MarkVarStoreIdUsed (VarStoreId
);
1897 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, IsBitVarStore
, Flag
)) == NULL
) {
1898 return VFR_RETURN_OUT_FOR_RESOURCES
;
1901 pNew
->mNext
= mBufferVarStoreList
;
1902 mBufferVarStoreList
= pNew
;
1904 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1905 return VFR_RETURN_FATAL_ERROR
;
1908 return VFR_RETURN_SUCCESS
;
1912 CVfrDataStorage::GetVarStoreByDataType (
1913 IN CHAR8
*DataTypeName
,
1914 OUT SVfrVarStorageNode
**VarNode
,
1915 IN EFI_GUID
*VarGuid
1918 SVfrVarStorageNode
*pNode
;
1919 SVfrVarStorageNode
*MatchNode
;
1922 // Framework VFR uses Data type name as varstore name, so don't need check again.
1924 if (VfrCompatibleMode
) {
1925 return VFR_RETURN_UNDEFINED
;
1929 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1930 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1934 if ((VarGuid
!= NULL
)) {
1935 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1937 return VFR_RETURN_SUCCESS
;
1940 if (MatchNode
== NULL
) {
1944 // More than one varstores referred the same data structures.
1946 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1951 if (MatchNode
== NULL
) {
1952 return VFR_RETURN_UNDEFINED
;
1955 *VarNode
= MatchNode
;
1956 return VFR_RETURN_SUCCESS
;
1960 CVfrDataStorage::CheckGuidField (
1961 IN SVfrVarStorageNode
*pNode
,
1962 IN EFI_GUID
*StoreGuid
,
1963 IN BOOLEAN
*HasFoundOne
,
1964 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1967 if (StoreGuid
!= NULL
) {
1969 // If has guid info, compare the guid filed.
1971 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1973 // Both name and guid are same, this this varstore.
1975 mCurrVarStorageNode
= pNode
;
1976 *ReturnCode
= VFR_RETURN_SUCCESS
;
1981 // Not has Guid field, check whether this name is the only one.
1985 // The name has conflict, return name redefined.
1987 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1991 *HasFoundOne
= TRUE
;
1992 mCurrVarStorageNode
= pNode
;
1999 Base on the input store name and guid to find the varstore id.
2001 If both name and guid are inputed, base on the name and guid to
2002 found the varstore. If only name inputed, base on the name to
2003 found the varstore and go on to check whether more than one varstore
2004 has the same name. If only has found one varstore, return this
2005 varstore; if more than one varstore has same name, return varstore
2006 name redefined error. If no varstore found by varstore name, call
2007 function GetVarStoreByDataType and use inputed varstore name as
2008 data type name to search.
2011 CVfrDataStorage::GetVarStoreId (
2012 IN CHAR8
*StoreName
,
2013 OUT EFI_VARSTORE_ID
*VarStoreId
,
2014 IN EFI_GUID
*StoreGuid
2017 EFI_VFR_RETURN_CODE ReturnCode
;
2018 SVfrVarStorageNode
*pNode
;
2019 BOOLEAN HasFoundOne
= FALSE
;
2021 mCurrVarStorageNode
= NULL
;
2023 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2024 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2025 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2026 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2032 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2033 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2034 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2035 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2041 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2042 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2043 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2044 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2051 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2052 return VFR_RETURN_SUCCESS
;
2055 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
2058 // Assume that Data strucutre name is used as StoreName, and check again.
2060 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
2061 if (pNode
!= NULL
) {
2062 mCurrVarStorageNode
= pNode
;
2063 *VarStoreId
= pNode
->mVarStoreId
;
2070 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2071 IN EFI_VARSTORE_ID VarStoreId
,
2072 OUT CHAR8
**DataTypeName
2075 SVfrVarStorageNode
*pNode
;
2077 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2078 return VFR_RETURN_FATAL_ERROR
;
2081 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2082 if (pNode
->mVarStoreId
== VarStoreId
) {
2083 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
2084 return VFR_RETURN_SUCCESS
;
2088 return VFR_RETURN_UNDEFINED
;
2091 EFI_VFR_VARSTORE_TYPE
2092 CVfrDataStorage::GetVarStoreType (
2093 IN EFI_VARSTORE_ID VarStoreId
2096 SVfrVarStorageNode
*pNode
;
2097 EFI_VFR_VARSTORE_TYPE VarStoreType
;
2099 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
2101 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2102 return VarStoreType
;
2105 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2106 if (pNode
->mVarStoreId
== VarStoreId
) {
2107 VarStoreType
= pNode
->mVarStoreType
;
2108 return VarStoreType
;
2112 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2113 if (pNode
->mVarStoreId
== VarStoreId
) {
2114 VarStoreType
= pNode
->mVarStoreType
;
2115 return VarStoreType
;
2119 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2120 if (pNode
->mVarStoreId
== VarStoreId
) {
2121 VarStoreType
= pNode
->mVarStoreType
;
2122 return VarStoreType
;
2126 return VarStoreType
;
2130 CVfrDataStorage::GetVarStoreGuid (
2131 IN EFI_VARSTORE_ID VarStoreId
2134 SVfrVarStorageNode
*pNode
;
2139 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2143 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2144 if (pNode
->mVarStoreId
== VarStoreId
) {
2145 VarGuid
= &pNode
->mGuid
;
2150 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2151 if (pNode
->mVarStoreId
== VarStoreId
) {
2152 VarGuid
= &pNode
->mGuid
;
2157 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2158 if (pNode
->mVarStoreId
== VarStoreId
) {
2159 VarGuid
= &pNode
->mGuid
;
2168 CVfrDataStorage::GetVarStoreName (
2169 IN EFI_VARSTORE_ID VarStoreId
,
2170 OUT CHAR8
**VarStoreName
2173 SVfrVarStorageNode
*pNode
;
2175 if (VarStoreName
== NULL
) {
2176 return VFR_RETURN_FATAL_ERROR
;
2179 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2180 if (pNode
->mVarStoreId
== VarStoreId
) {
2181 *VarStoreName
= pNode
->mVarStoreName
;
2182 return VFR_RETURN_SUCCESS
;
2186 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2187 if (pNode
->mVarStoreId
== VarStoreId
) {
2188 *VarStoreName
= pNode
->mVarStoreName
;
2189 return VFR_RETURN_SUCCESS
;
2193 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2194 if (pNode
->mVarStoreId
== VarStoreId
) {
2195 *VarStoreName
= pNode
->mVarStoreName
;
2196 return VFR_RETURN_SUCCESS
;
2200 *VarStoreName
= NULL
;
2201 return VFR_RETURN_UNDEFINED
;
2205 CVfrDataStorage::GetEfiVarStoreInfo (
2206 IN OUT EFI_VARSTORE_INFO
*Info
2210 return VFR_RETURN_FATAL_ERROR
;
2213 if (mCurrVarStorageNode
== NULL
) {
2214 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
2217 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
2218 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
2219 switch (Info
->mVarTotalSize
) {
2221 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
2224 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
2227 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
2230 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2233 return VFR_RETURN_FATAL_ERROR
;
2236 return VFR_RETURN_SUCCESS
;
2240 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2241 IN EFI_VARSTORE_INFO
*Info
2244 BufferVarStoreFieldInfoNode
*pNew
;
2246 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2247 return VFR_RETURN_FATAL_ERROR
;
2250 if (mBufferFieldInfoListHead
== NULL
) {
2251 mBufferFieldInfoListHead
= pNew
;
2252 mBufferFieldInfoListTail
= pNew
;
2254 mBufferFieldInfoListTail
->mNext
= pNew
;
2255 mBufferFieldInfoListTail
= pNew
;
2258 return VFR_RETURN_SUCCESS
;
2262 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2263 IN OUT EFI_VARSTORE_INFO
*Info
2266 BufferVarStoreFieldInfoNode
*pNode
;
2268 pNode
= mBufferFieldInfoListHead
;
2269 while (pNode
!= NULL
) {
2270 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2271 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2272 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2273 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2274 return VFR_RETURN_SUCCESS
;
2276 pNode
= pNode
->mNext
;
2278 return VFR_RETURN_FATAL_ERROR
;
2282 CVfrDataStorage::GetNameVarStoreInfo (
2283 OUT EFI_VARSTORE_INFO
*Info
,
2288 return VFR_RETURN_FATAL_ERROR
;
2291 if (mCurrVarStorageNode
== NULL
) {
2292 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2296 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2298 if (VfrCompatibleMode
) {
2300 return VFR_RETURN_ERROR_ARRARY_NUM
;
2305 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2307 return VFR_RETURN_SUCCESS
;
2310 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2311 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2313 IN EFI_STRING_ID DefaultStoreNameId
,
2317 mObjBinAddr
= ObjBinAddr
;
2319 if (RefName
!= NULL
) {
2320 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2321 strcpy (mRefName
, RefName
);
2327 mDefaultId
= DefaultId
;
2328 mDefaultStoreNameId
= DefaultStoreNameId
;
2331 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2335 if (mRefName
!= NULL
) {
2340 CVfrDefaultStore::CVfrDefaultStore (
2344 mDefaultStoreList
= NULL
;
2347 CVfrDefaultStore::~CVfrDefaultStore (
2351 SVfrDefaultStoreNode
*pTmp
= NULL
;
2353 while (mDefaultStoreList
!= NULL
) {
2354 pTmp
= mDefaultStoreList
;
2355 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2361 CVfrDefaultStore::RegisterDefaultStore (
2362 IN CHAR8
*ObjBinAddr
,
2364 IN EFI_STRING_ID DefaultStoreNameId
,
2368 SVfrDefaultStoreNode
*pNode
= NULL
;
2370 if (RefName
== NULL
) {
2371 return VFR_RETURN_FATAL_ERROR
;
2374 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2375 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2376 return VFR_RETURN_REDEFINED
;
2380 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2381 return VFR_RETURN_OUT_FOR_RESOURCES
;
2384 pNode
->mNext
= mDefaultStoreList
;
2385 mDefaultStoreList
= pNode
;
2387 return VFR_RETURN_SUCCESS
;
2391 * assign new reference name or new default store name id only if
2392 * the original is invalid
2395 CVfrDefaultStore::ReRegisterDefaultStoreById (
2396 IN UINT16 DefaultId
,
2398 IN EFI_STRING_ID DefaultStoreNameId
2401 SVfrDefaultStoreNode
*pNode
= NULL
;
2403 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2404 if (pNode
->mDefaultId
== DefaultId
) {
2409 if (pNode
== NULL
) {
2410 return VFR_RETURN_UNDEFINED
;
2412 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2413 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2414 if (pNode
->mObjBinAddr
!= NULL
) {
2415 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2418 return VFR_RETURN_REDEFINED
;
2421 if (RefName
!= NULL
) {
2422 delete pNode
->mRefName
;
2423 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2424 if (pNode
->mRefName
!= NULL
) {
2425 strcpy (pNode
->mRefName
, RefName
);
2430 return VFR_RETURN_SUCCESS
;
2434 CVfrDefaultStore::DefaultIdRegistered (
2438 SVfrDefaultStoreNode
*pNode
= NULL
;
2440 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2441 if (pNode
->mDefaultId
== DefaultId
) {
2450 CVfrDefaultStore::GetDefaultId (
2452 OUT UINT16
*DefaultId
2455 SVfrDefaultStoreNode
*pTmp
= NULL
;
2457 if (DefaultId
== NULL
) {
2458 return VFR_RETURN_FATAL_ERROR
;
2461 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2462 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2463 *DefaultId
= pTmp
->mDefaultId
;
2464 return VFR_RETURN_SUCCESS
;
2468 return VFR_RETURN_UNDEFINED
;
2472 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2473 IN EFI_VARSTORE_ID DefaultId
,
2474 IN EFI_VARSTORE_INFO
&Info
,
2475 IN CHAR8
*VarStoreName
,
2476 IN EFI_GUID
*VarStoreGuid
,
2478 IN EFI_IFR_TYPE_VALUE Value
2481 SVfrDefaultStoreNode
*pNode
= NULL
;
2482 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2483 INTN Returnvalue
= 0;
2485 if (VarStoreName
== NULL
) {
2486 return VFR_RETURN_FATAL_ERROR
;
2489 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2490 if (pNode
->mDefaultId
== DefaultId
) {
2495 if (pNode
== NULL
) {
2496 return VFR_RETURN_UNDEFINED
;
2499 gCVfrBufferConfig
.Open ();
2501 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2502 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2503 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2508 gCVfrBufferConfig
.Close ();
2510 return VFR_RETURN_SUCCESS
;
2513 gCVfrBufferConfig
.Close ();
2514 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2517 SVfrRuleNode::SVfrRuleNode (
2522 if (RuleName
!= NULL
) {
2523 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2524 strcpy (mRuleName
, RuleName
);
2533 SVfrRuleNode::~SVfrRuleNode (
2537 if (mRuleName
!= NULL
) {
2542 CVfrRulesDB::CVfrRulesDB ()
2545 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2548 CVfrRulesDB::~CVfrRulesDB ()
2550 SVfrRuleNode
*pNode
;
2552 while(mRuleList
!= NULL
) {
2554 mRuleList
= mRuleList
->mNext
;
2560 CVfrRulesDB::RegisterRule (
2566 if (RuleName
== NULL
) {
2570 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2576 pNew
->mNext
= mRuleList
;
2581 CVfrRulesDB::GetRuleId (
2585 SVfrRuleNode
*pNode
;
2587 if (RuleName
== NULL
) {
2588 return EFI_RULE_ID_INVALID
;
2591 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2592 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2593 return pNode
->mRuleId
;
2597 return EFI_RULE_ID_INVALID
;
2600 CVfrRulesDB gCVfrRulesDB
;
2602 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2606 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2607 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2608 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2609 mVarType
= EFI_IFR_TYPE_OTHER
;
2614 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2615 IN EFI_VARSTORE_INFO
&Info
2618 mVarStoreId
= Info
.mVarStoreId
;
2619 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2620 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2621 mVarType
= Info
.mVarType
;
2622 mVarTotalSize
= Info
.mVarTotalSize
;
2623 mIsBitVar
= Info
.mIsBitVar
;
2627 EFI_VARSTORE_INFO::operator= (
2628 IN CONST EFI_VARSTORE_INFO
&Info
2631 if (this != &Info
) {
2632 mVarStoreId
= Info
.mVarStoreId
;
2633 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2634 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2635 mVarType
= Info
.mVarType
;
2636 mVarTotalSize
= Info
.mVarTotalSize
;
2637 mIsBitVar
= Info
.mIsBitVar
;
2644 EFI_VARSTORE_INFO::operator == (
2645 IN EFI_VARSTORE_INFO
*Info
2648 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2649 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2650 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2651 (mVarType
== Info
->mVarType
) &&
2652 (mVarTotalSize
== Info
->mVarTotalSize
) &&
2653 (mIsBitVar
== Info
->mIsBitVar
)) {
2660 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2661 IN EFI_VARSTORE_INFO
*Info
2664 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2665 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2666 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2667 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2671 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2673 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2674 mVarStoreInfo
.mVarTotalSize
= 0;
2675 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2676 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2680 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2683 CVfrQuestionDB::GetFreeQuestionId (
2687 UINT32 Index
, Mask
, Offset
;
2689 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2690 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2695 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2696 return EFI_QUESTION_ID_INVALID
;
2699 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2700 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2701 mFreeQIdBitMap
[Index
] |= Mask
;
2702 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2706 return EFI_QUESTION_ID_INVALID
;
2710 CVfrQuestionDB::ChekQuestionIdFree (
2711 IN EFI_QUESTION_ID QId
2714 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2715 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2717 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2721 CVfrQuestionDB::MarkQuestionIdUsed (
2722 IN EFI_QUESTION_ID QId
2725 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2726 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2728 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2732 CVfrQuestionDB::MarkQuestionIdUnused (
2733 IN EFI_QUESTION_ID QId
2736 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2737 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2739 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2742 SVfrQuestionNode::SVfrQuestionNode (
2750 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2753 mQtype
= QUESTION_NORMAL
;
2756 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2757 strcpy (mName
, "$DEFAULT");
2759 mName
= new CHAR8
[strlen (Name
) + 1];
2760 strcpy (mName
, Name
);
2763 if (VarIdStr
!= NULL
) {
2764 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2765 strcpy (mVarIdStr
, VarIdStr
);
2767 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2768 strcpy (mVarIdStr
, "$");
2772 SVfrQuestionNode::~SVfrQuestionNode (
2776 if (mName
!= NULL
) {
2780 if (mVarIdStr
!= NULL
) {
2785 CVfrQuestionDB::CVfrQuestionDB ()
2789 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2790 mFreeQIdBitMap
[Index
] = 0;
2793 // Question ID 0 is reserved.
2794 mFreeQIdBitMap
[0] = 0x80000000;
2795 mQuestionList
= NULL
;
2798 CVfrQuestionDB::~CVfrQuestionDB ()
2800 SVfrQuestionNode
*pNode
;
2802 while (mQuestionList
!= NULL
) {
2803 pNode
= mQuestionList
;
2804 mQuestionList
= mQuestionList
->mNext
;
2810 // Reset to init state
2813 CVfrQuestionDB::ResetInit(
2818 SVfrQuestionNode
*pNode
;
2820 while (mQuestionList
!= NULL
) {
2821 pNode
= mQuestionList
;
2822 mQuestionList
= mQuestionList
->mNext
;
2826 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2827 mFreeQIdBitMap
[Index
] = 0;
2830 // Question ID 0 is reserved.
2831 mFreeQIdBitMap
[0] = 0x80000000;
2832 mQuestionList
= NULL
;
2836 CVfrQuestionDB::PrintAllQuestion (
2840 SVfrQuestionNode
*pNode
= NULL
;
2842 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2843 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2848 CVfrQuestionDB::RegisterQuestion (
2851 IN OUT EFI_QUESTION_ID
&QuestionId
2854 SVfrQuestionNode
*pNode
= NULL
;
2856 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2857 return VFR_RETURN_REDEFINED
;
2860 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2861 return VFR_RETURN_OUT_FOR_RESOURCES
;
2864 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2865 QuestionId
= GetFreeQuestionId ();
2868 // For Framework Vfr, don't check question ID conflict.
2870 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2872 return VFR_RETURN_QUESTIONID_REDEFINED
;
2874 MarkQuestionIdUsed (QuestionId
);
2876 pNode
->mQuestionId
= QuestionId
;
2878 pNode
->mNext
= mQuestionList
;
2879 mQuestionList
= pNode
;
2881 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2883 return VFR_RETURN_SUCCESS
;
2887 CVfrQuestionDB::RegisterOldDateQuestion (
2888 IN CHAR8
*YearVarId
,
2889 IN CHAR8
*MonthVarId
,
2891 IN OUT EFI_QUESTION_ID
&QuestionId
2894 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2897 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2901 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2904 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2907 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2911 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2912 QuestionId
= GetFreeQuestionId ();
2914 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2917 MarkQuestionIdUsed (QuestionId
);
2920 pNode
[0]->mQuestionId
= QuestionId
;
2921 pNode
[1]->mQuestionId
= QuestionId
;
2922 pNode
[2]->mQuestionId
= QuestionId
;
2923 pNode
[0]->mQtype
= QUESTION_DATE
;
2924 pNode
[1]->mQtype
= QUESTION_DATE
;
2925 pNode
[2]->mQtype
= QUESTION_DATE
;
2926 pNode
[0]->mNext
= pNode
[1];
2927 pNode
[1]->mNext
= pNode
[2];
2928 pNode
[2]->mNext
= mQuestionList
;
2929 mQuestionList
= pNode
[0];
2931 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2932 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2933 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2938 for (Index
= 0; Index
< 3; Index
++) {
2939 if (pNode
[Index
] != NULL
) {
2940 delete pNode
[Index
];
2943 QuestionId
= EFI_QUESTION_ID_INVALID
;
2947 CVfrQuestionDB::RegisterNewDateQuestion (
2949 IN CHAR8
*BaseVarId
,
2950 IN OUT EFI_QUESTION_ID
&QuestionId
2953 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2955 CHAR8
*VarIdStr
[3] = {NULL
, };
2958 if (BaseVarId
== NULL
&& Name
== NULL
) {
2959 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2960 QuestionId
= GetFreeQuestionId ();
2962 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2965 MarkQuestionIdUsed (QuestionId
);
2970 if (BaseVarId
!= NULL
) {
2971 Len
= strlen (BaseVarId
);
2973 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2974 if (VarIdStr
[0] != NULL
) {
2975 strcpy (VarIdStr
[0], BaseVarId
);
2976 strcat (VarIdStr
[0], ".Year");
2978 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2979 if (VarIdStr
[1] != NULL
) {
2980 strcpy (VarIdStr
[1], BaseVarId
);
2981 strcat (VarIdStr
[1], ".Month");
2983 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2984 if (VarIdStr
[2] != NULL
) {
2985 strcpy (VarIdStr
[2], BaseVarId
);
2986 strcat (VarIdStr
[2], ".Day");
2989 Len
= strlen (Name
);
2991 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2992 if (VarIdStr
[0] != NULL
) {
2993 strcpy (VarIdStr
[0], Name
);
2994 strcat (VarIdStr
[0], ".Year");
2996 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2997 if (VarIdStr
[1] != NULL
) {
2998 strcpy (VarIdStr
[1], Name
);
2999 strcat (VarIdStr
[1], ".Month");
3001 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
3002 if (VarIdStr
[2] != NULL
) {
3003 strcpy (VarIdStr
[2], Name
);
3004 strcat (VarIdStr
[2], ".Day");
3008 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
3011 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
3014 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
3018 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3019 QuestionId
= GetFreeQuestionId ();
3021 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3024 MarkQuestionIdUsed (QuestionId
);
3027 pNode
[0]->mQuestionId
= QuestionId
;
3028 pNode
[1]->mQuestionId
= QuestionId
;
3029 pNode
[2]->mQuestionId
= QuestionId
;
3030 pNode
[0]->mQtype
= QUESTION_DATE
;
3031 pNode
[1]->mQtype
= QUESTION_DATE
;
3032 pNode
[2]->mQtype
= QUESTION_DATE
;
3033 pNode
[0]->mNext
= pNode
[1];
3034 pNode
[1]->mNext
= pNode
[2];
3035 pNode
[2]->mNext
= mQuestionList
;
3036 mQuestionList
= pNode
[0];
3038 for (Index
= 0; Index
< 3; Index
++) {
3039 if (VarIdStr
[Index
] != NULL
) {
3040 delete VarIdStr
[Index
];
3044 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3045 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3046 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3051 for (Index
= 0; Index
< 3; Index
++) {
3052 if (pNode
[Index
] != NULL
) {
3053 delete pNode
[Index
];
3056 if (VarIdStr
[Index
] != NULL
) {
3057 delete VarIdStr
[Index
];
3063 CVfrQuestionDB::RegisterOldTimeQuestion (
3064 IN CHAR8
*HourVarId
,
3065 IN CHAR8
*MinuteVarId
,
3066 IN CHAR8
*SecondVarId
,
3067 IN OUT EFI_QUESTION_ID
&QuestionId
3070 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3073 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
3077 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
3080 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
3083 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
3087 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3088 QuestionId
= GetFreeQuestionId ();
3090 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3093 MarkQuestionIdUsed (QuestionId
);
3096 pNode
[0]->mQuestionId
= QuestionId
;
3097 pNode
[1]->mQuestionId
= QuestionId
;
3098 pNode
[2]->mQuestionId
= QuestionId
;
3099 pNode
[0]->mQtype
= QUESTION_TIME
;
3100 pNode
[1]->mQtype
= QUESTION_TIME
;
3101 pNode
[2]->mQtype
= QUESTION_TIME
;
3102 pNode
[0]->mNext
= pNode
[1];
3103 pNode
[1]->mNext
= pNode
[2];
3104 pNode
[2]->mNext
= mQuestionList
;
3105 mQuestionList
= pNode
[0];
3107 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3108 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3109 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3114 for (Index
= 0; Index
< 3; Index
++) {
3115 if (pNode
[Index
] != NULL
) {
3116 delete pNode
[Index
];
3119 QuestionId
= EFI_QUESTION_ID_INVALID
;
3123 CVfrQuestionDB::RegisterNewTimeQuestion (
3125 IN CHAR8
*BaseVarId
,
3126 IN OUT EFI_QUESTION_ID
&QuestionId
3129 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3131 CHAR8
*VarIdStr
[3] = {NULL
, };
3134 if (BaseVarId
== NULL
&& Name
== NULL
) {
3135 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3136 QuestionId
= GetFreeQuestionId ();
3138 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3141 MarkQuestionIdUsed (QuestionId
);
3146 if (BaseVarId
!= NULL
) {
3147 Len
= strlen (BaseVarId
);
3149 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3150 if (VarIdStr
[0] != NULL
) {
3151 strcpy (VarIdStr
[0], BaseVarId
);
3152 strcat (VarIdStr
[0], ".Hour");
3154 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3155 if (VarIdStr
[1] != NULL
) {
3156 strcpy (VarIdStr
[1], BaseVarId
);
3157 strcat (VarIdStr
[1], ".Minute");
3159 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3160 if (VarIdStr
[2] != NULL
) {
3161 strcpy (VarIdStr
[2], BaseVarId
);
3162 strcat (VarIdStr
[2], ".Second");
3165 Len
= strlen (Name
);
3167 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3168 if (VarIdStr
[0] != NULL
) {
3169 strcpy (VarIdStr
[0], Name
);
3170 strcat (VarIdStr
[0], ".Hour");
3172 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3173 if (VarIdStr
[1] != NULL
) {
3174 strcpy (VarIdStr
[1], Name
);
3175 strcat (VarIdStr
[1], ".Minute");
3177 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3178 if (VarIdStr
[2] != NULL
) {
3179 strcpy (VarIdStr
[2], Name
);
3180 strcat (VarIdStr
[2], ".Second");
3184 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
3187 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
3190 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
3194 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3195 QuestionId
= GetFreeQuestionId ();
3197 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3200 MarkQuestionIdUsed (QuestionId
);
3203 pNode
[0]->mQuestionId
= QuestionId
;
3204 pNode
[1]->mQuestionId
= QuestionId
;
3205 pNode
[2]->mQuestionId
= QuestionId
;
3206 pNode
[0]->mQtype
= QUESTION_TIME
;
3207 pNode
[1]->mQtype
= QUESTION_TIME
;
3208 pNode
[2]->mQtype
= QUESTION_TIME
;
3209 pNode
[0]->mNext
= pNode
[1];
3210 pNode
[1]->mNext
= pNode
[2];
3211 pNode
[2]->mNext
= mQuestionList
;
3212 mQuestionList
= pNode
[0];
3214 for (Index
= 0; Index
< 3; Index
++) {
3215 if (VarIdStr
[Index
] != NULL
) {
3216 delete VarIdStr
[Index
];
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
];
3239 CVfrQuestionDB::RegisterRefQuestion (
3241 IN CHAR8
*BaseVarId
,
3242 IN OUT EFI_QUESTION_ID
&QuestionId
3245 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3247 CHAR8
*VarIdStr
[4] = {NULL
, };
3250 if (BaseVarId
== NULL
&& Name
== NULL
) {
3254 if (BaseVarId
!= NULL
) {
3255 Len
= strlen (BaseVarId
);
3257 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3258 if (VarIdStr
[0] != NULL
) {
3259 strcpy (VarIdStr
[0], BaseVarId
);
3260 strcat (VarIdStr
[0], ".QuestionId");
3262 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3263 if (VarIdStr
[1] != NULL
) {
3264 strcpy (VarIdStr
[1], BaseVarId
);
3265 strcat (VarIdStr
[1], ".FormId");
3267 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3268 if (VarIdStr
[2] != NULL
) {
3269 strcpy (VarIdStr
[2], BaseVarId
);
3270 strcat (VarIdStr
[2], ".FormSetGuid");
3272 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3273 if (VarIdStr
[3] != NULL
) {
3274 strcpy (VarIdStr
[3], BaseVarId
);
3275 strcat (VarIdStr
[3], ".DevicePath");
3278 Len
= strlen (Name
);
3280 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3281 if (VarIdStr
[0] != NULL
) {
3282 strcpy (VarIdStr
[0], Name
);
3283 strcat (VarIdStr
[0], ".QuestionId");
3285 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3286 if (VarIdStr
[1] != NULL
) {
3287 strcpy (VarIdStr
[1], Name
);
3288 strcat (VarIdStr
[1], ".FormId");
3290 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3291 if (VarIdStr
[2] != NULL
) {
3292 strcpy (VarIdStr
[2], Name
);
3293 strcat (VarIdStr
[2], ".FormSetGuid");
3295 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3296 if (VarIdStr
[3] != NULL
) {
3297 strcpy (VarIdStr
[3], Name
);
3298 strcat (VarIdStr
[3], ".DevicePath");
3302 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3305 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3308 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3311 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3315 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3316 QuestionId
= GetFreeQuestionId ();
3318 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3321 MarkQuestionIdUsed (QuestionId
);
3324 pNode
[0]->mQuestionId
= QuestionId
;
3325 pNode
[1]->mQuestionId
= QuestionId
;
3326 pNode
[2]->mQuestionId
= QuestionId
;
3327 pNode
[3]->mQuestionId
= QuestionId
;
3328 pNode
[0]->mQtype
= QUESTION_REF
;
3329 pNode
[1]->mQtype
= QUESTION_REF
;
3330 pNode
[2]->mQtype
= QUESTION_REF
;
3331 pNode
[3]->mQtype
= QUESTION_REF
;
3332 pNode
[0]->mNext
= pNode
[1];
3333 pNode
[1]->mNext
= pNode
[2];
3334 pNode
[2]->mNext
= pNode
[3];
3335 pNode
[3]->mNext
= mQuestionList
;
3336 mQuestionList
= pNode
[0];
3338 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3339 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3340 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3341 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3346 for (Index
= 0; Index
< 4; Index
++) {
3347 if (pNode
[Index
] != NULL
) {
3348 delete pNode
[Index
];
3351 if (VarIdStr
[Index
] != NULL
) {
3352 delete VarIdStr
[Index
];
3358 CVfrQuestionDB::UpdateQuestionId (
3359 IN EFI_QUESTION_ID QId
,
3360 IN EFI_QUESTION_ID NewQId
3363 SVfrQuestionNode
*pNode
= NULL
;
3365 if (QId
== NewQId
) {
3367 return VFR_RETURN_SUCCESS
;
3371 // For Framework Vfr, don't check question ID conflict.
3373 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3374 return VFR_RETURN_REDEFINED
;
3377 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3378 if (pNode
->mQuestionId
== QId
) {
3383 if (pNode
== NULL
) {
3384 return VFR_RETURN_UNDEFINED
;
3387 MarkQuestionIdUnused (QId
);
3388 pNode
->mQuestionId
= NewQId
;
3389 MarkQuestionIdUsed (NewQId
);
3391 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3393 return VFR_RETURN_SUCCESS
;
3397 CVfrQuestionDB::GetQuestionId (
3400 OUT EFI_QUESTION_ID
&QuestionId
,
3401 OUT UINT32
&BitMask
,
3402 OUT EFI_QUESION_TYPE
*QType
3405 SVfrQuestionNode
*pNode
;
3407 QuestionId
= EFI_QUESTION_ID_INVALID
;
3408 BitMask
= 0x00000000;
3409 if (QType
!= NULL
) {
3410 *QType
= QUESTION_NORMAL
;
3413 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3417 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3419 if (strcmp (pNode
->mName
, Name
) != 0) {
3424 if (VarIdStr
!= NULL
) {
3425 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3430 QuestionId
= pNode
->mQuestionId
;
3431 BitMask
= pNode
->mBitMask
;
3432 if (QType
!= NULL
) {
3433 *QType
= pNode
->mQtype
;
3442 CVfrQuestionDB::FindQuestion (
3443 IN EFI_QUESTION_ID QuestionId
3446 SVfrQuestionNode
*pNode
;
3448 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3449 return VFR_RETURN_INVALID_PARAMETER
;
3452 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3453 if (pNode
->mQuestionId
== QuestionId
) {
3454 return VFR_RETURN_SUCCESS
;
3458 return VFR_RETURN_UNDEFINED
;
3462 CVfrQuestionDB::FindQuestion (
3466 SVfrQuestionNode
*pNode
;
3469 return VFR_RETURN_FATAL_ERROR
;
3472 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3473 if (strcmp (pNode
->mName
, Name
) == 0) {
3474 return VFR_RETURN_SUCCESS
;
3478 return VFR_RETURN_UNDEFINED
;
3481 CVfrStringDB::CVfrStringDB ()
3483 mStringFileName
= NULL
;
3486 CVfrStringDB::~CVfrStringDB ()
3488 if (mStringFileName
!= NULL
) {
3489 delete mStringFileName
;
3491 mStringFileName
= NULL
;
3496 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3500 if (StringFileName
== NULL
) {
3504 FileLen
= strlen (StringFileName
) + 1;
3505 mStringFileName
= new CHAR8
[FileLen
];
3506 if (mStringFileName
== NULL
) {
3510 strcpy (mStringFileName
, StringFileName
);
3511 mStringFileName
[FileLen
- 1] = '\0';
3516 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3517 from a set of supported languages.
3519 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3520 contains a set of language codes.
3521 @param[in] Language A variable that contains pointers to Null-terminated
3522 ASCII strings that contain one language codes.
3524 @retval FALSE The best matching language could not be found in SupportedLanguages.
3525 @retval TRUE The best matching language could be found in SupportedLanguages.
3529 CVfrStringDB::GetBestLanguage (
3530 IN CONST CHAR8
*SupportedLanguages
,
3534 UINTN CompareLength
;
3535 UINTN LanguageLength
;
3536 CONST CHAR8
*Supported
;
3538 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3543 // Determine the length of the first RFC 4646 language code in Language
3545 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3548 // Trim back the length of Language used until it is empty
3550 while (LanguageLength
> 0) {
3552 // Loop through all language codes in SupportedLanguages
3554 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3556 // Skip ';' characters in Supported
3558 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3560 // Determine the length of the next language code in Supported
3562 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3564 // If Language is longer than the Supported, then skip to the next language
3566 if (LanguageLength
> CompareLength
) {
3571 // See if the first LanguageLength characters in Supported match Language
3573 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3579 // Trim Language from the right to the next '-' character
3581 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3585 // No matches were found
3592 CVfrStringDB::GetVarStoreNameFormStringId (
3593 IN EFI_STRING_ID StringId
3596 FILE *pInFile
= NULL
;
3601 CHAR16
*UnicodeString
;
3602 CHAR8
*VarStoreName
= NULL
;
3606 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3608 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3610 if (mStringFileName
== NULL
) {
3614 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3621 fseek (pInFile
, 0, SEEK_END
);
3622 Length
= ftell (pInFile
);
3623 fseek (pInFile
, 0, SEEK_SET
);
3628 StringPtr
= new UINT8
[Length
];
3629 if (StringPtr
== NULL
) {
3633 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3636 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3638 // Check the String package.
3640 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3646 // Search the language, get best language base on RFC 4647 matching algorithm.
3648 Current
= StringPtr
;
3649 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3650 Current
+= PkgHeader
->Header
.Length
;
3651 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3653 // If can't find string package base on language, just return the first string package.
3655 if (Current
- StringPtr
>= Length
) {
3656 Current
= StringPtr
;
3657 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3662 Current
+= PkgHeader
->HdrSize
;
3664 // Find the string block according the stringId.
3666 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3667 if (Status
!= EFI_SUCCESS
) {
3673 // Get varstore name according the string type.
3675 switch (BlockType
) {
3676 case EFI_HII_SIBT_STRING_SCSU
:
3677 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3678 case EFI_HII_SIBT_STRINGS_SCSU
:
3679 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3680 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3681 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3682 strcpy (VarStoreName
, StringName
);
3684 case EFI_HII_SIBT_STRING_UCS2
:
3685 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3686 case EFI_HII_SIBT_STRINGS_UCS2
:
3687 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3688 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3689 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3690 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3691 VarStoreName
= DestTmp
;
3692 while (*UnicodeString
!= '\0') {
3693 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3703 return VarStoreName
;
3707 CVfrStringDB::FindStringBlock (
3708 IN UINT8
*StringData
,
3709 IN EFI_STRING_ID StringId
,
3710 OUT UINT32
*StringTextOffset
,
3711 OUT UINT8
*BlockType
3715 EFI_STRING_ID CurrentStringId
;
3718 UINT8
*StringTextPtr
;
3723 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3727 CurrentStringId
= 1;
3730 // Parse the string blocks to get the string text and font.
3732 BlockHdr
= StringData
;
3735 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3736 switch (*BlockHdr
) {
3737 case EFI_HII_SIBT_STRING_SCSU
:
3738 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3739 StringTextPtr
= BlockHdr
+ Offset
;
3740 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3744 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3745 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3746 StringTextPtr
= BlockHdr
+ Offset
;
3747 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3751 case EFI_HII_SIBT_STRINGS_SCSU
:
3752 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3753 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3754 BlockSize
+= StringTextPtr
- BlockHdr
;
3756 for (Index
= 0; Index
< StringCount
; Index
++) {
3757 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3758 if (CurrentStringId
== StringId
) {
3759 *BlockType
= *BlockHdr
;
3760 *StringTextOffset
= StringTextPtr
- StringData
;
3763 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3768 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3771 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3774 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3775 BlockSize
+= StringTextPtr
- BlockHdr
;
3777 for (Index
= 0; Index
< StringCount
; Index
++) {
3778 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3779 if (CurrentStringId
== StringId
) {
3780 *BlockType
= *BlockHdr
;
3781 *StringTextOffset
= StringTextPtr
- StringData
;
3784 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3789 case EFI_HII_SIBT_STRING_UCS2
:
3790 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3791 StringTextPtr
= BlockHdr
+ Offset
;
3793 // Use StringSize to store the size of the specified string, including the NULL
3796 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3797 BlockSize
+= Offset
+ StringSize
;
3801 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3802 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3803 StringTextPtr
= BlockHdr
+ Offset
;
3805 // Use StrSize to store the size of the specified string, including the NULL
3808 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3809 BlockSize
+= Offset
+ StringSize
;
3813 case EFI_HII_SIBT_STRINGS_UCS2
:
3814 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3815 StringTextPtr
= BlockHdr
+ Offset
;
3816 BlockSize
+= Offset
;
3817 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3818 for (Index
= 0; Index
< StringCount
; Index
++) {
3819 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3820 BlockSize
+= StringSize
;
3821 if (CurrentStringId
== StringId
) {
3822 *BlockType
= *BlockHdr
;
3823 *StringTextOffset
= StringTextPtr
- StringData
;
3826 StringTextPtr
= StringTextPtr
+ StringSize
;
3831 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3832 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3833 StringTextPtr
= BlockHdr
+ Offset
;
3834 BlockSize
+= Offset
;
3837 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3840 for (Index
= 0; Index
< StringCount
; Index
++) {
3841 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3842 BlockSize
+= StringSize
;
3843 if (CurrentStringId
== StringId
) {
3844 *BlockType
= *BlockHdr
;
3845 *StringTextOffset
= StringTextPtr
- StringData
;
3848 StringTextPtr
= StringTextPtr
+ StringSize
;
3853 case EFI_HII_SIBT_DUPLICATE
:
3854 if (CurrentStringId
== StringId
) {
3856 // Incoming StringId is an id of a duplicate string block.
3857 // Update the StringId to be the previous string block.
3858 // Go back to the header of string block to search.
3862 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3863 sizeof (EFI_STRING_ID
)
3865 CurrentStringId
= 1;
3868 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3873 case EFI_HII_SIBT_SKIP1
:
3874 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3875 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3876 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3879 case EFI_HII_SIBT_SKIP2
:
3880 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3881 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3882 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3885 case EFI_HII_SIBT_EXT1
:
3888 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3891 BlockSize
+= Length8
;
3894 case EFI_HII_SIBT_EXT2
:
3895 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3896 BlockSize
+= Ext2
.Length
;
3899 case EFI_HII_SIBT_EXT4
:
3902 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3906 BlockSize
+= Length32
;
3913 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3914 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3915 *BlockType
= *BlockHdr
;
3917 if (StringId
== CurrentStringId
- 1) {
3919 // if only one skip item, return EFI_NOT_FOUND.
3921 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3922 return EFI_NOT_FOUND
;
3928 if (StringId
< CurrentStringId
- 1) {
3929 return EFI_NOT_FOUND
;
3932 BlockHdr
= StringData
+ BlockSize
;
3935 return EFI_NOT_FOUND
;
3939 CVfrStringDB::GetUnicodeStringTextSize (
3946 StringSize
= sizeof (CHAR16
);
3947 StringPtr
= (UINT16
*)StringSrc
;
3948 while (*StringPtr
++ != L
'\0') {
3949 StringSize
+= sizeof (CHAR16
);
3955 BOOLEAN VfrCompatibleMode
= FALSE
;
3957 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3958 CVfrDefaultStore gCVfrDefaultStore
;
3959 CVfrDataStorage gCVfrDataStorage
;