3 Vfr common library functions.
5 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include "CommonLib.h"
14 #include "VfrUtilityLib.h"
15 #include "VfrFormPkg.h"
18 CVfrBinaryOutput::WriteLine (
21 IN CONST CHAR8
*LineHeader
,
28 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
32 for (Index
= 0; Index
< BlkSize
; Index
++) {
33 if ((Index
% LineBytes
) == 0) {
34 fprintf (pFile
, "\n%s", LineHeader
);
36 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
41 CVfrBinaryOutput::WriteEnd (
44 IN CONST CHAR8
*LineHeader
,
51 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
55 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
56 if ((Index
% LineBytes
) == 0) {
57 fprintf (pFile
, "\n%s", LineHeader
);
59 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
62 if ((Index
% LineBytes
) == 0) {
63 fprintf (pFile
, "\n%s", LineHeader
);
65 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
68 SConfigInfo::SConfigInfo (
72 IN EFI_IFR_TYPE_VALUE Value
77 mWidth
= (UINT16
)Width
;
78 mValue
= new UINT8
[mWidth
];
84 case EFI_IFR_TYPE_NUM_SIZE_8
:
85 memcpy (mValue
, &Value
.u8
, mWidth
);
87 case EFI_IFR_TYPE_NUM_SIZE_16
:
88 memcpy (mValue
, &Value
.u16
, mWidth
);
90 case EFI_IFR_TYPE_NUM_SIZE_32
:
91 memcpy (mValue
, &Value
.u32
, mWidth
);
93 case EFI_IFR_TYPE_NUM_SIZE_64
:
94 memcpy (mValue
, &Value
.u64
, mWidth
);
96 case EFI_IFR_TYPE_BOOLEAN
:
97 memcpy (mValue
, &Value
.b
, mWidth
);
99 case EFI_IFR_TYPE_TIME
:
100 memcpy (mValue
, &Value
.time
, mWidth
);
102 case EFI_IFR_TYPE_DATE
:
103 memcpy (mValue
, &Value
.date
, mWidth
);
105 case EFI_IFR_TYPE_STRING
:
106 memcpy (mValue
, &Value
.string
, mWidth
);
108 case EFI_IFR_TYPE_BUFFER
:
109 memcpy (mValue
, &Value
.u8
, mWidth
);
112 case EFI_IFR_TYPE_OTHER
:
117 SConfigInfo::~SConfigInfo (
121 ARRAY_SAFE_FREE (mValue
);
124 SConfigItem::SConfigItem (
137 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
138 strcpy (mName
, Name
);
143 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
144 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
149 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
155 SConfigItem::SConfigItem (
162 IN EFI_IFR_TYPE_VALUE Value
172 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
173 strcpy (mName
, Name
);
178 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
179 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
184 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
189 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
192 SConfigItem::~SConfigItem (
198 ARRAY_SAFE_FREE (mName
);
199 ARRAY_SAFE_FREE (mGuid
);
200 ARRAY_SAFE_FREE (mId
);
201 while (mInfoStrList
!= NULL
) {
203 mInfoStrList
= mInfoStrList
->mNext
;
205 BUFFER_SAFE_FREE (Info
);
210 CVfrBufferConfig::Register (
218 if (Select (Name
, Guid
) == 0) {
222 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
226 if (mItemListHead
== NULL
) {
227 mItemListHead
= pNew
;
228 mItemListTail
= pNew
;
230 mItemListTail
->mNext
= pNew
;
231 mItemListTail
= pNew
;
239 CVfrBufferConfig::Open (
243 mItemListPos
= mItemListHead
;
247 CVfrBufferConfig::Eof(
251 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
255 CVfrBufferConfig::Select (
263 if (Name
== NULL
|| Guid
== NULL
) {
264 mItemListPos
= mItemListHead
;
267 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
268 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
273 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
276 } else if (p
->mId
!= NULL
) {
289 CVfrBufferConfig::Write (
297 IN EFI_IFR_TYPE_VALUE Value
304 if ((Ret
= Select (Name
, Guid
)) != 0) {
310 if (Select (Name
, Guid
, Id
) != 0) {
311 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
314 if (mItemListHead
== NULL
) {
315 mItemListHead
= pItem
;
316 mItemListTail
= pItem
;
318 mItemListTail
->mNext
= pItem
;
319 mItemListTail
= pItem
;
321 mItemListPos
= pItem
;
323 // tranverse the list to find out if there's already the value for the same offset
324 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
325 if (pInfo
->mOffset
== Offset
) {
329 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
332 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
333 mItemListPos
->mInfoStrList
= pInfo
;
338 if (mItemListHead
== mItemListPos
) {
339 mItemListHead
= mItemListPos
->mNext
;
344 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
347 pItem
->mNext
= mItemListPos
->mNext
;
348 if (mItemListTail
== mItemListPos
) {
349 mItemListTail
= pItem
;
352 mItemListPos
= pItem
->mNext
;
355 case 'i' : // set info
356 if (mItemListPos
->mId
!= NULL
) {
357 delete[] mItemListPos
->mId
;
359 mItemListPos
->mId
= NULL
;
361 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
364 strcpy (mItemListPos
->mId
, Id
);
377 CVfrBufferConfig::Close (
384 #define BYTES_PRE_LINE 0x10
387 CVfrBufferConfig::OutputCFile (
392 CVfrBinaryOutput Output
;
401 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
402 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
405 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
407 TotalLen
= sizeof (UINT32
);
408 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
409 TotalLen
+= sizeof (UINT16
) * 2;
411 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
413 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
414 fprintf (pFile
, "\n");
415 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
418 fprintf (pFile
, "\n};\n");
421 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
422 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
423 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
425 TotalLen
= sizeof (UINT32
);
426 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
427 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
429 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
431 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
432 fprintf (pFile
, "\n");
433 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
435 if (Info
->mNext
== NULL
) {
436 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
438 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
441 fprintf (pFile
, "\n};\n");
446 CVfrBufferConfig::CVfrBufferConfig (
450 mItemListHead
= NULL
;
451 mItemListTail
= NULL
;
455 CVfrBufferConfig::~CVfrBufferConfig (
461 while (mItemListHead
!= NULL
) {
463 mItemListHead
= mItemListHead
->mNext
;
467 mItemListHead
= NULL
;
468 mItemListTail
= NULL
;
472 CVfrBufferConfig gCVfrBufferConfig
;
475 CONST CHAR8
*mTypeName
;
479 } gInternalTypesTable
[] = {
480 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
481 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
482 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
483 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
484 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
485 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
486 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
487 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
488 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
489 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
500 if (TypeName
== NULL
) {
504 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
505 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
522 while (*Str
&& *Str
== ' ') {
525 while (*Str
&& *Str
== '0') {
528 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
545 Str
= TrimHex (Str
, &IsHex
);
546 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
548 // BUG: does not handle overflow here
550 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
552 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
553 Value
+= (c
- 'a' + 10);
555 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
556 Value
+= (c
- 'A' + 10);
558 if (c
>= '0' && c
<= '9') {
567 CVfrVarDataTypeDB::RegisterNewType (
571 New
->mNext
= mDataTypeList
;
576 CVfrVarDataTypeDB::ExtractStructTypeName (
582 return VFR_RETURN_FATAL_ERROR
;
585 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
591 if (*VarStr
== '.') {
595 return VFR_RETURN_SUCCESS
;
599 Check whether the DataType contain bit field.
601 @param TypeName The name of the type.
605 CVfrVarDataTypeDB::DataTypeHasBitField (
609 SVfrDataType
*pType
= NULL
;
612 GetDataType (TypeName
, &pType
);
617 for (pTmp
= pType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
618 if (pTmp
->mIsBitField
) {
626 Check whether the field is bit field or not.
628 @param VarStr Point to the field name which may contain the structure name.
632 CVfrVarDataTypeDB::IsThisBitField (
636 CHAR8 FName
[MAX_NAME_LEN
];
637 CHAR8 TName
[MAX_NAME_LEN
];
639 SVfrDataType
*pType
= NULL
;
640 SVfrDataField
*pField
= NULL
;
642 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
643 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
645 while (*VarStr
!= '\0') {
646 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
647 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
648 pType
= pField
->mFieldType
;
650 if (pField
!= NULL
&& pField
->mIsBitField
) {
658 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
665 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
667 ArrayIdx
= INVALID_ARRAY_INDEX
;
670 return VFR_RETURN_FATAL_ERROR
;
673 while((*VarStr
!= '\0') &&
687 return VFR_RETURN_SUCCESS
;
690 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
691 ArrayStr
[Idx
] = *VarStr
;
693 ArrayStr
[Idx
] = '\0';
695 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
696 return VFR_RETURN_DATA_STRING_ERROR
;
698 ArrayIdx
= _STR2U32 (ArrayStr
);
699 if (*VarStr
== ']') {
702 if (*VarStr
== '.') {
705 return VFR_RETURN_SUCCESS
;
707 return VFR_RETURN_DATA_STRING_ERROR
;
710 return VFR_RETURN_SUCCESS
;
714 CVfrVarDataTypeDB::GetTypeField (
715 IN CONST CHAR8
*FName
,
716 IN SVfrDataType
*Type
,
717 OUT SVfrDataField
*&Field
720 SVfrDataField
*pField
= NULL
;
722 if ((FName
== NULL
) || (Type
== NULL
)) {
723 return VFR_RETURN_FATAL_ERROR
;
726 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
728 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
729 // add code to adjust it.
731 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
732 if (strcmp (FName
, "Hour") == 0) {
734 } else if (strcmp (FName
, "Minute") == 0) {
736 } else if (strcmp (FName
, "Second") == 0) {
741 if (strcmp (pField
->mFieldName
, FName
) == 0) {
743 return VFR_RETURN_SUCCESS
;
747 return VFR_RETURN_UNDEFINED
;
751 CVfrVarDataTypeDB::GetFieldOffset (
752 IN SVfrDataField
*Field
,
755 IN BOOLEAN IsBitField
759 return VFR_RETURN_FATAL_ERROR
;
762 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
763 return VFR_RETURN_ERROR_ARRARY_NUM
;
767 // Be compatible with the current usage
768 // If ArraryIdx is not specified, the first one is used.
770 // if ArrayNum is larger than zero, ArraryIdx must be specified.
772 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
773 // return VFR_RETURN_ERROR_ARRARY_NUM;
777 Offset
= Field
->mBitOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
) * 8;
779 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
781 return VFR_RETURN_SUCCESS
;
785 CVfrVarDataTypeDB::GetFieldWidth (
786 IN SVfrDataField
*Field
793 return Field
->mFieldType
->mType
;
797 CVfrVarDataTypeDB::GetFieldSize (
798 IN SVfrDataField
*Field
,
804 return VFR_RETURN_FATAL_ERROR
;
807 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
808 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
811 return Field
->mBitWidth
;
813 return Field
->mFieldType
->mTotalSize
;
819 CVfrVarDataTypeDB::InternalTypesListInit (
823 SVfrDataType
*New
= NULL
;
826 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
827 New
= new SVfrDataType
;
829 assert (strlen (gInternalTypesTable
[Index
].mTypeName
) < MAX_NAME_LEN
);
830 strncpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
, MAX_NAME_LEN
- 1);
831 New
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
832 New
->mType
= gInternalTypesTable
[Index
].mType
;
833 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
834 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
835 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
836 SVfrDataField
*pYearField
= new SVfrDataField
;
837 SVfrDataField
*pMonthField
= new SVfrDataField
;
838 SVfrDataField
*pDayField
= new SVfrDataField
;
840 strcpy (pYearField
->mFieldName
, "Year");
841 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
842 pYearField
->mOffset
= 0;
843 pYearField
->mNext
= pMonthField
;
844 pYearField
->mArrayNum
= 0;
845 pYearField
->mIsBitField
= FALSE
;
847 strcpy (pMonthField
->mFieldName
, "Month");
848 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
849 pMonthField
->mOffset
= 2;
850 pMonthField
->mNext
= pDayField
;
851 pMonthField
->mArrayNum
= 0;
852 pMonthField
->mIsBitField
= FALSE
;
854 strcpy (pDayField
->mFieldName
, "Day");
855 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
856 pDayField
->mOffset
= 3;
857 pDayField
->mNext
= NULL
;
858 pDayField
->mArrayNum
= 0;
859 pDayField
->mIsBitField
= FALSE
;
861 New
->mMembers
= pYearField
;
862 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
863 SVfrDataField
*pHoursField
= new SVfrDataField
;
864 SVfrDataField
*pMinutesField
= new SVfrDataField
;
865 SVfrDataField
*pSecondsField
= new SVfrDataField
;
867 strcpy (pHoursField
->mFieldName
, "Hours");
868 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
869 pHoursField
->mOffset
= 0;
870 pHoursField
->mNext
= pMinutesField
;
871 pHoursField
->mArrayNum
= 0;
872 pHoursField
->mIsBitField
= FALSE
;
874 strcpy (pMinutesField
->mFieldName
, "Minutes");
875 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
876 pMinutesField
->mOffset
= 1;
877 pMinutesField
->mNext
= pSecondsField
;
878 pMinutesField
->mArrayNum
= 0;
879 pMinutesField
->mIsBitField
= FALSE
;
881 strcpy (pSecondsField
->mFieldName
, "Seconds");
882 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
883 pSecondsField
->mOffset
= 2;
884 pSecondsField
->mNext
= NULL
;
885 pSecondsField
->mArrayNum
= 0;
886 pSecondsField
->mIsBitField
= FALSE
;
888 New
->mMembers
= pHoursField
;
889 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
890 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
891 SVfrDataField
*pFormIdField
= new SVfrDataField
;
892 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
893 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
895 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
896 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
897 pQuestionIdField
->mOffset
= 0;
898 pQuestionIdField
->mNext
= pFormIdField
;
899 pQuestionIdField
->mArrayNum
= 0;
900 pQuestionIdField
->mIsBitField
= FALSE
;
902 strcpy (pFormIdField
->mFieldName
, "FormId");
903 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
904 pFormIdField
->mOffset
= 2;
905 pFormIdField
->mNext
= pFormSetGuidField
;
906 pFormIdField
->mArrayNum
= 0;
907 pFormIdField
->mIsBitField
= FALSE
;
909 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
910 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
911 pFormSetGuidField
->mOffset
= 4;
912 pFormSetGuidField
->mNext
= pDevicePathField
;
913 pFormSetGuidField
->mArrayNum
= 0;
914 pFormSetGuidField
->mIsBitField
= FALSE
;
916 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
917 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
918 pDevicePathField
->mOffset
= 20;
919 pDevicePathField
->mNext
= NULL
;
920 pDevicePathField
->mArrayNum
= 0;
921 pDevicePathField
->mIsBitField
= FALSE
;
923 New
->mMembers
= pQuestionIdField
;
925 New
->mMembers
= NULL
;
928 RegisterNewType (New
);
934 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
938 mDataTypeList
= NULL
;
940 mCurrDataField
= NULL
;
941 mPackAlign
= DEFAULT_PACK_ALIGN
;
943 mFirstNewDataTypeName
= NULL
;
944 mCurrDataType
= NULL
;
946 InternalTypesListInit ();
949 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
954 SVfrDataField
*pField
;
955 SVfrPackStackNode
*pPack
;
957 if (mNewDataType
!= NULL
) {
961 while (mDataTypeList
!= NULL
) {
962 pType
= mDataTypeList
;
963 mDataTypeList
= mDataTypeList
->mNext
;
964 while(pType
->mMembers
!= NULL
) {
965 pField
= pType
->mMembers
;
966 pType
->mMembers
= pType
->mMembers
->mNext
;
972 while (mPackStack
!= NULL
) {
974 mPackStack
= mPackStack
->mNext
;
980 CVfrVarDataTypeDB::Pack (
983 IN CHAR8
*Identifier
,
988 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
990 if (Action
& VFR_PACK_SHOW
) {
991 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
992 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
995 if (Action
& VFR_PACK_PUSH
) {
996 SVfrPackStackNode
*pNew
= NULL
;
998 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
999 return VFR_RETURN_FATAL_ERROR
;
1001 pNew
->mNext
= mPackStack
;
1005 if (Action
& VFR_PACK_POP
) {
1006 SVfrPackStackNode
*pNode
= NULL
;
1008 if (mPackStack
== NULL
) {
1009 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
1012 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1013 if (pNode
->Match (Identifier
) == TRUE
) {
1014 mPackAlign
= pNode
->mNumber
;
1015 mPackStack
= pNode
->mNext
;
1020 if (Action
& VFR_PACK_ASSIGN
) {
1021 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
1022 if ((PackAlign
== 0) || (PackAlign
> 16)) {
1023 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
1025 mPackAlign
= PackAlign
;
1029 return VFR_RETURN_SUCCESS
;
1033 CVfrVarDataTypeDB::DeclareDataTypeBegin (
1037 SVfrDataType
*pNewType
= NULL
;
1039 pNewType
= new SVfrDataType
;
1040 pNewType
->mTypeName
[0] = '\0';
1041 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
1042 pNewType
->mAlign
= DEFAULT_ALIGN
;
1043 pNewType
->mTotalSize
= 0;
1044 pNewType
->mMembers
= NULL
;
1045 pNewType
->mNext
= NULL
;
1046 pNewType
->mHasBitField
= FALSE
;
1048 mNewDataType
= pNewType
;
1052 CVfrVarDataTypeDB::SetNewTypeName (
1056 SVfrDataType
*pType
;
1058 if (mNewDataType
== NULL
) {
1059 return VFR_RETURN_ERROR_SKIPED
;
1061 if (TypeName
== NULL
) {
1062 return VFR_RETURN_FATAL_ERROR
;
1064 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
1065 return VFR_RETURN_INVALID_PARAMETER
;
1068 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1069 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1070 return VFR_RETURN_REDEFINED
;
1074 strncpy(mNewDataType
->mTypeName
, TypeName
, MAX_NAME_LEN
- 1);
1075 mNewDataType
->mTypeName
[MAX_NAME_LEN
- 1] = 0;
1076 return VFR_RETURN_SUCCESS
;
1080 Record the bit field info in the data type.
1082 @param FieldName Point to the field name.
1083 @param TypeName Point to the type name.
1084 @param Width The bit width.
1085 @param FieldInUnion The filed is in Union type or Structure type.
1089 CVfrVarDataTypeDB::DataTypeAddBitField (
1090 IN CHAR8
*FieldName
,
1093 IN BOOLEAN FieldInUnion
1096 SVfrDataField
*pNewField
= NULL
;
1097 SVfrDataType
*pFieldType
= NULL
;
1098 SVfrDataField
*pTmp
;
1100 UINT32 MaxDataTypeSize
;
1101 BOOLEAN UpdateTotalSize
;
1103 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1105 if (Width
> MAX_BIT_WIDTH
) {
1106 return VFR_RETURN_BIT_WIDTH_ERROR
;
1109 if (Width
> pFieldType
->mTotalSize
* 8) {
1110 return VFR_RETURN_BIT_WIDTH_ERROR
;
1113 if (FieldName
!= NULL
&& strlen (FieldName
) >= MAX_NAME_LEN
) {
1114 return VFR_RETURN_INVALID_PARAMETER
;
1117 if (Width
== 0 && FieldName
!= NULL
) {
1118 return VFR_RETURN_INVALID_PARAMETER
;
1121 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1122 if (FieldName
!= NULL
&& strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1123 return VFR_RETURN_REDEFINED
;
1127 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1128 UpdateTotalSize
= FALSE
;
1130 if ((pNewField
= new SVfrDataField
) == NULL
) {
1131 return VFR_RETURN_OUT_FOR_RESOURCES
;
1134 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1135 if (FieldName
!= NULL
) {
1136 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1137 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1139 strncpy (pNewField
->mFieldName
, "", MAX_NAME_LEN
- 1);
1141 pNewField
->mFieldType
= pFieldType
;
1142 pNewField
->mIsBitField
= TRUE
;
1143 pNewField
->mBitWidth
= Width
;
1144 pNewField
->mArrayNum
= 0;
1145 pNewField
->mBitOffset
= 0;
1146 pNewField
->mOffset
= 0;
1148 if (mNewDataType
->mMembers
== NULL
) {
1149 mNewDataType
->mMembers
= pNewField
;
1150 pNewField
->mNext
= NULL
;
1152 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1154 pTmp
->mNext
= pNewField
;
1155 pNewField
->mNext
= NULL
;
1159 pNewField
->mOffset
= 0;
1160 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1161 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1165 // Check whether the bit fields can be contained within one FieldType.
1167 if (pTmp
!= NULL
&& pTmp
->mIsBitField
&& strcmp (pTmp
->mFieldType
->mTypeName
, pNewField
->mFieldType
->mTypeName
) == 0 &&
1168 (pTmp
->mBitOffset
- pTmp
->mOffset
* 8) + pTmp
->mBitWidth
+ pNewField
->mBitWidth
<= pNewField
->mFieldType
->mTotalSize
* 8) {
1169 pNewField
->mBitOffset
= pTmp
->mBitOffset
+ pTmp
->mBitWidth
;
1170 pNewField
->mOffset
= pTmp
->mOffset
;
1172 // If BitWidth=0,used to force alignment at the next word boundary.
1173 // So make this bit field occupy the remaing bit width of current field type.
1175 if (pNewField
->mBitWidth
== 0) {
1176 pNewField
->mBitWidth
= pNewField
->mFieldType
->mTotalSize
* 8 - (pNewField
->mBitOffset
- pTmp
->mOffset
* 8);
1180 // The bit filed start a new memory
1182 pNewField
->mBitOffset
= mNewDataType
->mTotalSize
* 8;
1183 UpdateTotalSize
= TRUE
;
1187 if (UpdateTotalSize
){
1188 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1189 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1191 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1193 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
);
1196 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1197 mNewDataType
->mHasBitField
= TRUE
;
1198 return VFR_RETURN_SUCCESS
;
1202 CVfrVarDataTypeDB::DataTypeAddField (
1203 IN CHAR8
*FieldName
,
1206 IN BOOLEAN FieldInUnion
1209 SVfrDataField
*pNewField
= NULL
;
1210 SVfrDataType
*pFieldType
= NULL
;
1211 SVfrDataField
*pTmp
;
1213 UINT32 MaxDataTypeSize
;
1215 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1216 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1218 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1219 return VFR_RETURN_INVALID_PARAMETER
;
1222 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1223 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1224 return VFR_RETURN_REDEFINED
;
1228 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1230 if ((pNewField
= new SVfrDataField
) == NULL
) {
1231 return VFR_RETURN_OUT_FOR_RESOURCES
;
1233 strncpy (pNewField
->mFieldName
, FieldName
, MAX_NAME_LEN
- 1);
1234 pNewField
->mFieldName
[MAX_NAME_LEN
- 1] = 0;
1235 pNewField
->mFieldType
= pFieldType
;
1236 pNewField
->mArrayNum
= ArrayNum
;
1237 pNewField
->mIsBitField
= FALSE
;
1238 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1239 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1241 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1243 if (mNewDataType
->mMembers
== NULL
) {
1244 mNewDataType
->mMembers
= pNewField
;
1245 pNewField
->mNext
= NULL
;
1247 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1249 pTmp
->mNext
= pNewField
;
1250 pNewField
->mNext
= NULL
;
1253 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1256 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1257 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1259 pNewField
->mOffset
= 0;
1261 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1264 return VFR_RETURN_SUCCESS
;
1268 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1272 if (mNewDataType
->mTypeName
[0] == '\0') {
1276 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1277 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1280 RegisterNewType (mNewDataType
);
1281 if (mFirstNewDataTypeName
== NULL
) {
1282 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1285 mNewDataType
= NULL
;
1289 CVfrVarDataTypeDB::GetDataType (
1291 OUT SVfrDataType
**DataType
1294 SVfrDataType
*pDataType
= NULL
;
1296 if (TypeName
== NULL
) {
1297 return VFR_RETURN_ERROR_SKIPED
;
1300 if (DataType
== NULL
) {
1301 return VFR_RETURN_FATAL_ERROR
;
1306 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1307 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1308 *DataType
= pDataType
;
1309 return VFR_RETURN_SUCCESS
;
1313 return VFR_RETURN_UNDEFINED
;
1317 CVfrVarDataTypeDB::GetDataTypeSize (
1322 SVfrDataType
*pDataType
= NULL
;
1325 return VFR_RETURN_FATAL_ERROR
;
1329 DataType
= DataType
& 0x0F;
1332 // For user defined data type, the size can't be got by this function.
1334 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1335 return VFR_RETURN_SUCCESS
;
1338 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1339 if (DataType
== pDataType
->mType
) {
1340 *Size
= pDataType
->mTotalSize
;
1341 return VFR_RETURN_SUCCESS
;
1345 return VFR_RETURN_UNDEFINED
;
1349 CVfrVarDataTypeDB::GetDataTypeSize (
1354 SVfrDataType
*pDataType
= NULL
;
1357 return VFR_RETURN_FATAL_ERROR
;
1362 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1363 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1364 *Size
= pDataType
->mTotalSize
;
1365 return VFR_RETURN_SUCCESS
;
1369 return VFR_RETURN_UNDEFINED
;
1373 CVfrVarDataTypeDB::GetDataFieldInfo (
1378 OUT BOOLEAN
&BitField
1381 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1382 UINT32 ArrayIdx
, Tmp
;
1383 SVfrDataType
*pType
= NULL
;
1384 SVfrDataField
*pField
= NULL
;
1388 Type
= EFI_IFR_TYPE_OTHER
;
1390 VarStrName
= VarStr
;
1392 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1393 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1395 BitField
= IsThisBitField (VarStrName
);
1398 // if it is not struct data type
1400 Type
= pType
->mType
;
1401 Size
= pType
->mTotalSize
;
1403 while (*VarStr
!= '\0') {
1404 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1405 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1406 pType
= pField
->mFieldType
;
1407 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
, pField
->mIsBitField
), VFR_RETURN_SUCCESS
);
1408 if (BitField
&& !pField
->mIsBitField
) {
1409 Offset
= (UINT16
) (Offset
+ Tmp
* 8);
1411 Offset
= (UINT16
) (Offset
+ Tmp
);
1413 Type
= GetFieldWidth (pField
);
1414 Size
= GetFieldSize (pField
, ArrayIdx
, BitField
);
1416 return VFR_RETURN_SUCCESS
;
1420 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1421 OUT CHAR8
***NameList
,
1422 OUT UINT32
*ListSize
1426 SVfrDataType
*pType
;
1428 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1429 return VFR_RETURN_FATAL_ERROR
;
1435 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1436 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1441 if (*ListSize
== 0) {
1442 return VFR_RETURN_SUCCESS
;
1445 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1447 return VFR_RETURN_OUT_FOR_RESOURCES
;
1450 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1451 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1452 (*NameList
)[Index
] = pType
->mTypeName
;
1455 return VFR_RETURN_SUCCESS
;
1459 CVfrVarDataTypeDB::IsTypeNameDefined (
1463 SVfrDataType
*pType
;
1465 if (TypeName
== NULL
) {
1469 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1470 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1479 CVfrVarDataTypeDB::Dump (
1483 SVfrDataType
*pTNode
;
1484 SVfrDataField
*pFNode
;
1486 fprintf (File
, "\n\n***************************************************************\n");
1487 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1488 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1489 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1490 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1491 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1492 if (pFNode
->mArrayNum
> 0) {
1493 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1494 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1496 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1497 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1500 fprintf (File
, "\t\t};\n");
1501 fprintf (File
, "---------------------------------------------------------------\n");
1503 fprintf (File
, "***************************************************************\n");
1506 #ifdef CVFR_VARDATATYPEDB_DEBUG
1508 CVfrVarDataTypeDB::ParserDB (
1512 SVfrDataType
*pTNode
;
1513 SVfrDataField
*pFNode
;
1515 printf ("***************************************************************\n");
1516 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1517 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1518 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1519 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1520 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1521 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1523 printf ("\t\t};\n");
1524 printf ("---------------------------------------------------------------\n");
1526 printf ("***************************************************************\n");
1530 SVfrVarStorageNode::SVfrVarStorageNode (
1532 IN CHAR8
*StoreName
,
1533 IN EFI_VARSTORE_ID VarStoreId
,
1534 IN EFI_STRING_ID VarName
,
1542 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1544 if (StoreName
!= NULL
) {
1545 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1546 strcpy (mVarStoreName
, StoreName
);
1548 mVarStoreName
= NULL
;
1551 mVarStoreId
= VarStoreId
;
1552 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1553 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1554 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1555 mAssignedFlag
= Flag
;
1558 SVfrVarStorageNode::SVfrVarStorageNode (
1560 IN CHAR8
*StoreName
,
1561 IN EFI_VARSTORE_ID VarStoreId
,
1562 IN SVfrDataType
*DataType
,
1563 IN BOOLEAN BitsVarstore
,
1570 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1572 if (StoreName
!= NULL
) {
1573 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1574 strcpy (mVarStoreName
, StoreName
);
1576 mVarStoreName
= NULL
;
1579 mVarStoreId
= VarStoreId
;
1581 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER_BITS
;
1583 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1585 mStorageInfo
.mDataType
= DataType
;
1586 mAssignedFlag
= Flag
;
1589 SVfrVarStorageNode::SVfrVarStorageNode (
1590 IN CHAR8
*StoreName
,
1591 IN EFI_VARSTORE_ID VarStoreId
1594 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1595 if (StoreName
!= NULL
) {
1596 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1597 strcpy (mVarStoreName
, StoreName
);
1599 mVarStoreName
= NULL
;
1602 mVarStoreId
= VarStoreId
;
1603 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1604 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1605 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1606 mAssignedFlag
= FALSE
;
1609 SVfrVarStorageNode::~SVfrVarStorageNode (
1613 if (mVarStoreName
!= NULL
) {
1614 delete[] mVarStoreName
;
1617 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1618 delete[] mStorageInfo
.mNameSpace
.mNameTable
;
1622 CVfrDataStorage::CVfrDataStorage (
1628 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1629 mFreeVarStoreIdBitMap
[Index
] = 0;
1632 // Question ID 0 is reserved.
1633 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1635 mBufferVarStoreList
= NULL
;
1636 mEfiVarStoreList
= NULL
;
1637 mNameVarStoreList
= NULL
;
1638 mCurrVarStorageNode
= NULL
;
1639 mNewVarStorageNode
= NULL
;
1640 mBufferFieldInfoListHead
= NULL
;
1641 mBufferFieldInfoListTail
= NULL
;
1644 CVfrDataStorage::~CVfrDataStorage (
1648 SVfrVarStorageNode
*pNode
;
1650 while (mBufferVarStoreList
!= NULL
) {
1651 pNode
= mBufferVarStoreList
;
1652 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1655 while (mEfiVarStoreList
!= NULL
) {
1656 pNode
= mEfiVarStoreList
;
1657 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1660 while (mNameVarStoreList
!= NULL
) {
1661 pNode
= mNameVarStoreList
;
1662 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1665 if (mNewVarStorageNode
!= NULL
) {
1666 delete mNewVarStorageNode
;
1671 CVfrDataStorage::GetFreeVarStoreId (
1672 EFI_VFR_VARSTORE_TYPE VarType
1675 UINT32 Index
, Mask
, Offset
;
1679 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1680 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1685 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1686 return EFI_VARSTORE_ID_INVALID
;
1689 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1690 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1691 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1692 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1696 return EFI_VARSTORE_ID_INVALID
;
1700 CVfrDataStorage::ChekVarStoreIdFree (
1701 IN EFI_VARSTORE_ID VarStoreId
1704 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1705 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1707 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1711 CVfrDataStorage::MarkVarStoreIdUsed (
1712 IN EFI_VARSTORE_ID VarStoreId
1715 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1716 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1718 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1722 CVfrDataStorage::MarkVarStoreIdUnused (
1723 IN EFI_VARSTORE_ID VarStoreId
1726 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1727 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1729 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1733 CVfrDataStorage::DeclareNameVarStoreBegin (
1734 IN CHAR8
*StoreName
,
1735 IN EFI_VARSTORE_ID VarStoreId
1738 SVfrVarStorageNode
*pNode
= NULL
;
1739 EFI_VARSTORE_ID TmpVarStoreId
;
1741 if (StoreName
== NULL
) {
1742 return VFR_RETURN_FATAL_ERROR
;
1745 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1746 return VFR_RETURN_REDEFINED
;
1749 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1750 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1752 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1753 return VFR_RETURN_VARSTOREID_REDEFINED
;
1755 MarkVarStoreIdUsed (VarStoreId
);
1758 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1759 return VFR_RETURN_UNDEFINED
;
1762 mNewVarStorageNode
= pNode
;
1764 return VFR_RETURN_SUCCESS
;
1768 CVfrDataStorage::NameTableAddItem (
1769 IN EFI_STRING_ID Item
1772 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1775 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1776 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1778 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1779 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1780 return VFR_RETURN_OUT_FOR_RESOURCES
;
1782 memcpy (NewTable
, OldTable
, TableSize
);
1783 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1786 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1787 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1789 return VFR_RETURN_SUCCESS
;
1793 CVfrDataStorage::DeclareNameVarStoreEnd (
1797 mNewVarStorageNode
->mGuid
= *Guid
;
1798 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1799 mNameVarStoreList
= mNewVarStorageNode
;
1801 mNewVarStorageNode
= NULL
;
1803 return VFR_RETURN_SUCCESS
;
1807 CVfrDataStorage::DeclareEfiVarStore (
1808 IN CHAR8
*StoreName
,
1810 IN EFI_STRING_ID NameStrId
,
1815 SVfrVarStorageNode
*pNode
;
1816 EFI_VARSTORE_ID VarStoreId
;
1818 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1819 return VFR_RETURN_FATAL_ERROR
;
1822 if (VarSize
> sizeof (UINT64
)) {
1823 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1826 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1827 return VFR_RETURN_REDEFINED
;
1830 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1831 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1832 return VFR_RETURN_OUT_FOR_RESOURCES
;
1835 pNode
->mNext
= mEfiVarStoreList
;
1836 mEfiVarStoreList
= pNode
;
1838 return VFR_RETURN_SUCCESS
;
1842 CVfrDataStorage::DeclareBufferVarStore (
1843 IN CHAR8
*StoreName
,
1845 IN CVfrVarDataTypeDB
*DataTypeDB
,
1847 IN EFI_VARSTORE_ID VarStoreId
,
1848 IN BOOLEAN IsBitVarStore
,
1852 SVfrVarStorageNode
*pNew
= NULL
;
1853 SVfrDataType
*pDataType
= NULL
;
1854 EFI_VARSTORE_ID TempVarStoreId
;
1856 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1857 return VFR_RETURN_FATAL_ERROR
;
1860 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1861 return VFR_RETURN_REDEFINED
;
1864 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1866 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1867 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1869 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1870 return VFR_RETURN_VARSTOREID_REDEFINED
;
1872 MarkVarStoreIdUsed (VarStoreId
);
1875 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, IsBitVarStore
, Flag
)) == NULL
) {
1876 return VFR_RETURN_OUT_FOR_RESOURCES
;
1879 pNew
->mNext
= mBufferVarStoreList
;
1880 mBufferVarStoreList
= pNew
;
1882 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1883 return VFR_RETURN_FATAL_ERROR
;
1886 return VFR_RETURN_SUCCESS
;
1890 CVfrDataStorage::GetVarStoreByDataType (
1891 IN CHAR8
*DataTypeName
,
1892 OUT SVfrVarStorageNode
**VarNode
,
1893 IN EFI_GUID
*VarGuid
1896 SVfrVarStorageNode
*pNode
;
1897 SVfrVarStorageNode
*MatchNode
;
1900 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1901 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1905 if ((VarGuid
!= NULL
)) {
1906 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1908 return VFR_RETURN_SUCCESS
;
1911 if (MatchNode
== NULL
) {
1915 // More than one varstores referred the same data structures.
1917 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1922 if (MatchNode
== NULL
) {
1923 return VFR_RETURN_UNDEFINED
;
1926 *VarNode
= MatchNode
;
1927 return VFR_RETURN_SUCCESS
;
1931 CVfrDataStorage::CheckGuidField (
1932 IN SVfrVarStorageNode
*pNode
,
1933 IN EFI_GUID
*StoreGuid
,
1934 IN BOOLEAN
*HasFoundOne
,
1935 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1938 if (StoreGuid
!= NULL
) {
1940 // If has guid info, compare the guid filed.
1942 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1944 // Both name and guid are same, this this varstore.
1946 mCurrVarStorageNode
= pNode
;
1947 *ReturnCode
= VFR_RETURN_SUCCESS
;
1952 // Not has Guid field, check whether this name is the only one.
1956 // The name has conflict, return name redefined.
1958 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1962 *HasFoundOne
= TRUE
;
1963 mCurrVarStorageNode
= pNode
;
1970 Base on the input store name and guid to find the varstore id.
1972 If both name and guid are inputed, base on the name and guid to
1973 found the varstore. If only name inputed, base on the name to
1974 found the varstore and go on to check whether more than one varstore
1975 has the same name. If only has found one varstore, return this
1976 varstore; if more than one varstore has same name, return varstore
1977 name redefined error. If no varstore found by varstore name, call
1978 function GetVarStoreByDataType and use inputed varstore name as
1979 data type name to search.
1982 CVfrDataStorage::GetVarStoreId (
1983 IN CHAR8
*StoreName
,
1984 OUT EFI_VARSTORE_ID
*VarStoreId
,
1985 IN EFI_GUID
*StoreGuid
1988 EFI_VFR_RETURN_CODE ReturnCode
;
1989 SVfrVarStorageNode
*pNode
;
1990 BOOLEAN HasFoundOne
= FALSE
;
1992 mCurrVarStorageNode
= NULL
;
1994 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1995 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1996 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1997 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2003 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2004 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2005 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2006 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2012 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2013 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
2014 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
2015 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2022 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
2023 return VFR_RETURN_SUCCESS
;
2026 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
2029 // Assume that Data structure name is used as StoreName, and check again.
2031 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
2032 if (pNode
!= NULL
) {
2033 mCurrVarStorageNode
= pNode
;
2034 *VarStoreId
= pNode
->mVarStoreId
;
2041 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2042 IN EFI_VARSTORE_ID VarStoreId
,
2043 OUT CHAR8
**DataTypeName
2046 SVfrVarStorageNode
*pNode
;
2048 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2049 return VFR_RETURN_FATAL_ERROR
;
2052 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2053 if (pNode
->mVarStoreId
== VarStoreId
) {
2054 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
2055 return VFR_RETURN_SUCCESS
;
2059 return VFR_RETURN_UNDEFINED
;
2062 EFI_VFR_VARSTORE_TYPE
2063 CVfrDataStorage::GetVarStoreType (
2064 IN EFI_VARSTORE_ID VarStoreId
2067 SVfrVarStorageNode
*pNode
;
2068 EFI_VFR_VARSTORE_TYPE VarStoreType
;
2070 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
2072 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2073 return VarStoreType
;
2076 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2077 if (pNode
->mVarStoreId
== VarStoreId
) {
2078 VarStoreType
= pNode
->mVarStoreType
;
2079 return VarStoreType
;
2083 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2084 if (pNode
->mVarStoreId
== VarStoreId
) {
2085 VarStoreType
= pNode
->mVarStoreType
;
2086 return VarStoreType
;
2090 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2091 if (pNode
->mVarStoreId
== VarStoreId
) {
2092 VarStoreType
= pNode
->mVarStoreType
;
2093 return VarStoreType
;
2097 return VarStoreType
;
2101 CVfrDataStorage::GetVarStoreGuid (
2102 IN EFI_VARSTORE_ID VarStoreId
2105 SVfrVarStorageNode
*pNode
;
2110 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
2114 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2115 if (pNode
->mVarStoreId
== VarStoreId
) {
2116 VarGuid
= &pNode
->mGuid
;
2121 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2122 if (pNode
->mVarStoreId
== VarStoreId
) {
2123 VarGuid
= &pNode
->mGuid
;
2128 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2129 if (pNode
->mVarStoreId
== VarStoreId
) {
2130 VarGuid
= &pNode
->mGuid
;
2139 CVfrDataStorage::GetVarStoreName (
2140 IN EFI_VARSTORE_ID VarStoreId
,
2141 OUT CHAR8
**VarStoreName
2144 SVfrVarStorageNode
*pNode
;
2146 if (VarStoreName
== NULL
) {
2147 return VFR_RETURN_FATAL_ERROR
;
2150 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2151 if (pNode
->mVarStoreId
== VarStoreId
) {
2152 *VarStoreName
= pNode
->mVarStoreName
;
2153 return VFR_RETURN_SUCCESS
;
2157 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2158 if (pNode
->mVarStoreId
== VarStoreId
) {
2159 *VarStoreName
= pNode
->mVarStoreName
;
2160 return VFR_RETURN_SUCCESS
;
2164 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2165 if (pNode
->mVarStoreId
== VarStoreId
) {
2166 *VarStoreName
= pNode
->mVarStoreName
;
2167 return VFR_RETURN_SUCCESS
;
2171 *VarStoreName
= NULL
;
2172 return VFR_RETURN_UNDEFINED
;
2176 CVfrDataStorage::GetEfiVarStoreInfo (
2177 IN OUT EFI_VARSTORE_INFO
*Info
2181 return VFR_RETURN_FATAL_ERROR
;
2184 if (mCurrVarStorageNode
== NULL
) {
2185 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
2188 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
2189 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
2190 switch (Info
->mVarTotalSize
) {
2192 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
2195 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
2198 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
2201 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2204 return VFR_RETURN_FATAL_ERROR
;
2207 return VFR_RETURN_SUCCESS
;
2211 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2212 IN EFI_VARSTORE_INFO
*Info
2215 BufferVarStoreFieldInfoNode
*pNew
;
2217 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2218 return VFR_RETURN_FATAL_ERROR
;
2221 if (mBufferFieldInfoListHead
== NULL
) {
2222 mBufferFieldInfoListHead
= pNew
;
2223 mBufferFieldInfoListTail
= pNew
;
2225 mBufferFieldInfoListTail
->mNext
= pNew
;
2226 mBufferFieldInfoListTail
= pNew
;
2229 return VFR_RETURN_SUCCESS
;
2233 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2234 IN OUT EFI_VARSTORE_INFO
*Info
2237 BufferVarStoreFieldInfoNode
*pNode
;
2239 pNode
= mBufferFieldInfoListHead
;
2240 while (pNode
!= NULL
) {
2241 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2242 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2243 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2244 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2245 return VFR_RETURN_SUCCESS
;
2247 pNode
= pNode
->mNext
;
2249 return VFR_RETURN_FATAL_ERROR
;
2253 CVfrDataStorage::GetNameVarStoreInfo (
2254 OUT EFI_VARSTORE_INFO
*Info
,
2259 return VFR_RETURN_FATAL_ERROR
;
2262 if (mCurrVarStorageNode
== NULL
) {
2263 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2266 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2268 return VFR_RETURN_SUCCESS
;
2271 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2272 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2274 IN EFI_STRING_ID DefaultStoreNameId
,
2278 mObjBinAddr
= ObjBinAddr
;
2280 if (RefName
!= NULL
) {
2281 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2282 strcpy (mRefName
, RefName
);
2288 mDefaultId
= DefaultId
;
2289 mDefaultStoreNameId
= DefaultStoreNameId
;
2292 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2296 if (mRefName
!= NULL
) {
2301 CVfrDefaultStore::CVfrDefaultStore (
2305 mDefaultStoreList
= NULL
;
2308 CVfrDefaultStore::~CVfrDefaultStore (
2312 SVfrDefaultStoreNode
*pTmp
= NULL
;
2314 while (mDefaultStoreList
!= NULL
) {
2315 pTmp
= mDefaultStoreList
;
2316 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2322 CVfrDefaultStore::RegisterDefaultStore (
2323 IN CHAR8
*ObjBinAddr
,
2325 IN EFI_STRING_ID DefaultStoreNameId
,
2329 SVfrDefaultStoreNode
*pNode
= NULL
;
2331 if (RefName
== NULL
) {
2332 return VFR_RETURN_FATAL_ERROR
;
2335 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2336 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2337 return VFR_RETURN_REDEFINED
;
2341 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2342 return VFR_RETURN_OUT_FOR_RESOURCES
;
2345 pNode
->mNext
= mDefaultStoreList
;
2346 mDefaultStoreList
= pNode
;
2348 return VFR_RETURN_SUCCESS
;
2352 * assign new reference name or new default store name id only if
2353 * the original is invalid
2356 CVfrDefaultStore::ReRegisterDefaultStoreById (
2357 IN UINT16 DefaultId
,
2359 IN EFI_STRING_ID DefaultStoreNameId
2362 SVfrDefaultStoreNode
*pNode
= NULL
;
2364 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2365 if (pNode
->mDefaultId
== DefaultId
) {
2370 if (pNode
== NULL
) {
2371 return VFR_RETURN_UNDEFINED
;
2373 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2374 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2375 if (pNode
->mObjBinAddr
!= NULL
) {
2376 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2379 return VFR_RETURN_REDEFINED
;
2382 if (RefName
!= NULL
) {
2383 delete pNode
->mRefName
;
2384 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2385 if (pNode
->mRefName
!= NULL
) {
2386 strcpy (pNode
->mRefName
, RefName
);
2391 return VFR_RETURN_SUCCESS
;
2395 CVfrDefaultStore::DefaultIdRegistered (
2399 SVfrDefaultStoreNode
*pNode
= NULL
;
2401 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2402 if (pNode
->mDefaultId
== DefaultId
) {
2411 CVfrDefaultStore::GetDefaultId (
2413 OUT UINT16
*DefaultId
2416 SVfrDefaultStoreNode
*pTmp
= NULL
;
2418 if (DefaultId
== NULL
) {
2419 return VFR_RETURN_FATAL_ERROR
;
2422 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2423 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2424 *DefaultId
= pTmp
->mDefaultId
;
2425 return VFR_RETURN_SUCCESS
;
2429 return VFR_RETURN_UNDEFINED
;
2433 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2434 IN EFI_VARSTORE_ID DefaultId
,
2435 IN EFI_VARSTORE_INFO
&Info
,
2436 IN CHAR8
*VarStoreName
,
2437 IN EFI_GUID
*VarStoreGuid
,
2439 IN EFI_IFR_TYPE_VALUE Value
2442 SVfrDefaultStoreNode
*pNode
= NULL
;
2443 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2444 INTN Returnvalue
= 0;
2446 if (VarStoreName
== NULL
) {
2447 return VFR_RETURN_FATAL_ERROR
;
2450 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2451 if (pNode
->mDefaultId
== DefaultId
) {
2456 if (pNode
== NULL
) {
2457 return VFR_RETURN_UNDEFINED
;
2460 gCVfrBufferConfig
.Open ();
2462 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2463 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2464 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2469 gCVfrBufferConfig
.Close ();
2471 return VFR_RETURN_SUCCESS
;
2474 gCVfrBufferConfig
.Close ();
2475 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2478 SVfrRuleNode::SVfrRuleNode (
2483 if (RuleName
!= NULL
) {
2484 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2485 strcpy (mRuleName
, RuleName
);
2494 SVfrRuleNode::~SVfrRuleNode (
2498 if (mRuleName
!= NULL
) {
2503 CVfrRulesDB::CVfrRulesDB ()
2506 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2509 CVfrRulesDB::~CVfrRulesDB ()
2511 SVfrRuleNode
*pNode
;
2513 while(mRuleList
!= NULL
) {
2515 mRuleList
= mRuleList
->mNext
;
2521 CVfrRulesDB::RegisterRule (
2527 if (RuleName
== NULL
) {
2531 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2537 pNew
->mNext
= mRuleList
;
2542 CVfrRulesDB::GetRuleId (
2546 SVfrRuleNode
*pNode
;
2548 if (RuleName
== NULL
) {
2549 return EFI_RULE_ID_INVALID
;
2552 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2553 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2554 return pNode
->mRuleId
;
2558 return EFI_RULE_ID_INVALID
;
2561 CVfrRulesDB gCVfrRulesDB
;
2563 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2567 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2568 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2569 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2570 mVarType
= EFI_IFR_TYPE_OTHER
;
2575 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2576 IN EFI_VARSTORE_INFO
&Info
2579 mVarStoreId
= Info
.mVarStoreId
;
2580 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2581 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2582 mVarType
= Info
.mVarType
;
2583 mVarTotalSize
= Info
.mVarTotalSize
;
2584 mIsBitVar
= Info
.mIsBitVar
;
2588 EFI_VARSTORE_INFO::operator= (
2589 IN CONST EFI_VARSTORE_INFO
&Info
2592 if (this != &Info
) {
2593 mVarStoreId
= Info
.mVarStoreId
;
2594 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2595 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2596 mVarType
= Info
.mVarType
;
2597 mVarTotalSize
= Info
.mVarTotalSize
;
2598 mIsBitVar
= Info
.mIsBitVar
;
2605 EFI_VARSTORE_INFO::operator == (
2606 IN EFI_VARSTORE_INFO
*Info
2609 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2610 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2611 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2612 (mVarType
== Info
->mVarType
) &&
2613 (mVarTotalSize
== Info
->mVarTotalSize
) &&
2614 (mIsBitVar
== Info
->mIsBitVar
)) {
2621 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2622 IN EFI_VARSTORE_INFO
*Info
2625 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2626 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2627 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2628 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2632 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2634 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2635 mVarStoreInfo
.mVarTotalSize
= 0;
2636 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2637 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2641 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2644 CVfrQuestionDB::GetFreeQuestionId (
2648 UINT32 Index
, Mask
, Offset
;
2650 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2651 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2656 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2657 return EFI_QUESTION_ID_INVALID
;
2660 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2661 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2662 mFreeQIdBitMap
[Index
] |= Mask
;
2663 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2667 return EFI_QUESTION_ID_INVALID
;
2671 CVfrQuestionDB::ChekQuestionIdFree (
2672 IN EFI_QUESTION_ID QId
2675 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2676 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2678 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2682 CVfrQuestionDB::MarkQuestionIdUsed (
2683 IN EFI_QUESTION_ID QId
2686 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2687 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2689 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2693 CVfrQuestionDB::MarkQuestionIdUnused (
2694 IN EFI_QUESTION_ID QId
2697 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2698 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2700 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2703 SVfrQuestionNode::SVfrQuestionNode (
2711 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2714 mQtype
= QUESTION_NORMAL
;
2717 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2718 strcpy (mName
, "$DEFAULT");
2720 mName
= new CHAR8
[strlen (Name
) + 1];
2721 strcpy (mName
, Name
);
2724 if (VarIdStr
!= NULL
) {
2725 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2726 strcpy (mVarIdStr
, VarIdStr
);
2728 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2729 strcpy (mVarIdStr
, "$");
2733 SVfrQuestionNode::~SVfrQuestionNode (
2737 if (mName
!= NULL
) {
2741 if (mVarIdStr
!= NULL
) {
2746 CVfrQuestionDB::CVfrQuestionDB ()
2750 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2751 mFreeQIdBitMap
[Index
] = 0;
2754 // Question ID 0 is reserved.
2755 mFreeQIdBitMap
[0] = 0x80000000;
2756 mQuestionList
= NULL
;
2759 CVfrQuestionDB::~CVfrQuestionDB ()
2761 SVfrQuestionNode
*pNode
;
2763 while (mQuestionList
!= NULL
) {
2764 pNode
= mQuestionList
;
2765 mQuestionList
= mQuestionList
->mNext
;
2771 // Reset to init state
2774 CVfrQuestionDB::ResetInit(
2779 SVfrQuestionNode
*pNode
;
2781 while (mQuestionList
!= NULL
) {
2782 pNode
= mQuestionList
;
2783 mQuestionList
= mQuestionList
->mNext
;
2787 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2788 mFreeQIdBitMap
[Index
] = 0;
2791 // Question ID 0 is reserved.
2792 mFreeQIdBitMap
[0] = 0x80000000;
2793 mQuestionList
= NULL
;
2797 CVfrQuestionDB::PrintAllQuestion (
2801 SVfrQuestionNode
*pNode
= NULL
;
2803 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2804 printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2809 CVfrQuestionDB::RegisterQuestion (
2812 IN OUT EFI_QUESTION_ID
&QuestionId
2815 SVfrQuestionNode
*pNode
= NULL
;
2817 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2818 return VFR_RETURN_REDEFINED
;
2821 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2822 return VFR_RETURN_OUT_FOR_RESOURCES
;
2825 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2826 QuestionId
= GetFreeQuestionId ();
2828 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2830 return VFR_RETURN_QUESTIONID_REDEFINED
;
2832 MarkQuestionIdUsed (QuestionId
);
2834 pNode
->mQuestionId
= QuestionId
;
2836 pNode
->mNext
= mQuestionList
;
2837 mQuestionList
= pNode
;
2839 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2841 return VFR_RETURN_SUCCESS
;
2845 CVfrQuestionDB::RegisterOldDateQuestion (
2846 IN CHAR8
*YearVarId
,
2847 IN CHAR8
*MonthVarId
,
2849 IN OUT EFI_QUESTION_ID
&QuestionId
2852 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2855 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2859 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2862 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2865 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2869 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2870 QuestionId
= GetFreeQuestionId ();
2872 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2875 MarkQuestionIdUsed (QuestionId
);
2878 pNode
[0]->mQuestionId
= QuestionId
;
2879 pNode
[1]->mQuestionId
= QuestionId
;
2880 pNode
[2]->mQuestionId
= QuestionId
;
2881 pNode
[0]->mQtype
= QUESTION_DATE
;
2882 pNode
[1]->mQtype
= QUESTION_DATE
;
2883 pNode
[2]->mQtype
= QUESTION_DATE
;
2884 pNode
[0]->mNext
= pNode
[1];
2885 pNode
[1]->mNext
= pNode
[2];
2886 pNode
[2]->mNext
= mQuestionList
;
2887 mQuestionList
= pNode
[0];
2889 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2890 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2891 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2896 for (Index
= 0; Index
< 3; Index
++) {
2897 if (pNode
[Index
] != NULL
) {
2898 delete pNode
[Index
];
2901 QuestionId
= EFI_QUESTION_ID_INVALID
;
2905 CVfrQuestionDB::RegisterNewDateQuestion (
2907 IN CHAR8
*BaseVarId
,
2908 IN OUT EFI_QUESTION_ID
&QuestionId
2911 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2913 CHAR8
*VarIdStr
[3] = {NULL
, };
2916 if (BaseVarId
== NULL
&& Name
== NULL
) {
2917 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2918 QuestionId
= GetFreeQuestionId ();
2920 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2923 MarkQuestionIdUsed (QuestionId
);
2928 if (BaseVarId
!= NULL
) {
2929 Len
= strlen (BaseVarId
);
2931 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2932 if (VarIdStr
[0] != NULL
) {
2933 strcpy (VarIdStr
[0], BaseVarId
);
2934 strcat (VarIdStr
[0], ".Year");
2936 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2937 if (VarIdStr
[1] != NULL
) {
2938 strcpy (VarIdStr
[1], BaseVarId
);
2939 strcat (VarIdStr
[1], ".Month");
2941 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2942 if (VarIdStr
[2] != NULL
) {
2943 strcpy (VarIdStr
[2], BaseVarId
);
2944 strcat (VarIdStr
[2], ".Day");
2947 Len
= strlen (Name
);
2949 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2950 if (VarIdStr
[0] != NULL
) {
2951 strcpy (VarIdStr
[0], Name
);
2952 strcat (VarIdStr
[0], ".Year");
2954 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2955 if (VarIdStr
[1] != NULL
) {
2956 strcpy (VarIdStr
[1], Name
);
2957 strcat (VarIdStr
[1], ".Month");
2959 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2960 if (VarIdStr
[2] != NULL
) {
2961 strcpy (VarIdStr
[2], Name
);
2962 strcat (VarIdStr
[2], ".Day");
2966 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2969 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2972 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2976 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2977 QuestionId
= GetFreeQuestionId ();
2979 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2982 MarkQuestionIdUsed (QuestionId
);
2985 pNode
[0]->mQuestionId
= QuestionId
;
2986 pNode
[1]->mQuestionId
= QuestionId
;
2987 pNode
[2]->mQuestionId
= QuestionId
;
2988 pNode
[0]->mQtype
= QUESTION_DATE
;
2989 pNode
[1]->mQtype
= QUESTION_DATE
;
2990 pNode
[2]->mQtype
= QUESTION_DATE
;
2991 pNode
[0]->mNext
= pNode
[1];
2992 pNode
[1]->mNext
= pNode
[2];
2993 pNode
[2]->mNext
= mQuestionList
;
2994 mQuestionList
= pNode
[0];
2996 for (Index
= 0; Index
< 3; Index
++) {
2997 if (VarIdStr
[Index
] != NULL
) {
2998 delete[] VarIdStr
[Index
];
2999 VarIdStr
[Index
] = NULL
;
3003 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3004 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3005 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3010 for (Index
= 0; Index
< 3; Index
++) {
3011 if (pNode
[Index
] != NULL
) {
3012 delete pNode
[Index
];
3015 if (VarIdStr
[Index
] != NULL
) {
3016 delete[] VarIdStr
[Index
];
3017 VarIdStr
[Index
] = NULL
;
3023 CVfrQuestionDB::RegisterOldTimeQuestion (
3024 IN CHAR8
*HourVarId
,
3025 IN CHAR8
*MinuteVarId
,
3026 IN CHAR8
*SecondVarId
,
3027 IN OUT EFI_QUESTION_ID
&QuestionId
3030 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3033 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
3037 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
3040 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
3043 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
3047 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3048 QuestionId
= GetFreeQuestionId ();
3050 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3053 MarkQuestionIdUsed (QuestionId
);
3056 pNode
[0]->mQuestionId
= QuestionId
;
3057 pNode
[1]->mQuestionId
= QuestionId
;
3058 pNode
[2]->mQuestionId
= QuestionId
;
3059 pNode
[0]->mQtype
= QUESTION_TIME
;
3060 pNode
[1]->mQtype
= QUESTION_TIME
;
3061 pNode
[2]->mQtype
= QUESTION_TIME
;
3062 pNode
[0]->mNext
= pNode
[1];
3063 pNode
[1]->mNext
= pNode
[2];
3064 pNode
[2]->mNext
= mQuestionList
;
3065 mQuestionList
= pNode
[0];
3067 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3068 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3069 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3074 for (Index
= 0; Index
< 3; Index
++) {
3075 if (pNode
[Index
] != NULL
) {
3076 delete pNode
[Index
];
3079 QuestionId
= EFI_QUESTION_ID_INVALID
;
3083 CVfrQuestionDB::RegisterNewTimeQuestion (
3085 IN CHAR8
*BaseVarId
,
3086 IN OUT EFI_QUESTION_ID
&QuestionId
3089 SVfrQuestionNode
*pNode
[3] = {NULL
, };
3091 CHAR8
*VarIdStr
[3] = {NULL
, };
3094 if (BaseVarId
== NULL
&& Name
== NULL
) {
3095 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3096 QuestionId
= GetFreeQuestionId ();
3098 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3101 MarkQuestionIdUsed (QuestionId
);
3106 if (BaseVarId
!= NULL
) {
3107 Len
= strlen (BaseVarId
);
3109 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3110 if (VarIdStr
[0] != NULL
) {
3111 strcpy (VarIdStr
[0], BaseVarId
);
3112 strcat (VarIdStr
[0], ".Hour");
3114 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3115 if (VarIdStr
[1] != NULL
) {
3116 strcpy (VarIdStr
[1], BaseVarId
);
3117 strcat (VarIdStr
[1], ".Minute");
3119 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3120 if (VarIdStr
[2] != NULL
) {
3121 strcpy (VarIdStr
[2], BaseVarId
);
3122 strcat (VarIdStr
[2], ".Second");
3125 Len
= strlen (Name
);
3127 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
3128 if (VarIdStr
[0] != NULL
) {
3129 strcpy (VarIdStr
[0], Name
);
3130 strcat (VarIdStr
[0], ".Hour");
3132 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
3133 if (VarIdStr
[1] != NULL
) {
3134 strcpy (VarIdStr
[1], Name
);
3135 strcat (VarIdStr
[1], ".Minute");
3137 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
3138 if (VarIdStr
[2] != NULL
) {
3139 strcpy (VarIdStr
[2], Name
);
3140 strcat (VarIdStr
[2], ".Second");
3144 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
3147 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
3150 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
3154 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3155 QuestionId
= GetFreeQuestionId ();
3157 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3160 MarkQuestionIdUsed (QuestionId
);
3163 pNode
[0]->mQuestionId
= QuestionId
;
3164 pNode
[1]->mQuestionId
= QuestionId
;
3165 pNode
[2]->mQuestionId
= QuestionId
;
3166 pNode
[0]->mQtype
= QUESTION_TIME
;
3167 pNode
[1]->mQtype
= QUESTION_TIME
;
3168 pNode
[2]->mQtype
= QUESTION_TIME
;
3169 pNode
[0]->mNext
= pNode
[1];
3170 pNode
[1]->mNext
= pNode
[2];
3171 pNode
[2]->mNext
= mQuestionList
;
3172 mQuestionList
= pNode
[0];
3174 for (Index
= 0; Index
< 3; Index
++) {
3175 if (VarIdStr
[Index
] != NULL
) {
3176 delete[] VarIdStr
[Index
];
3177 VarIdStr
[Index
] = NULL
;
3181 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3182 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3183 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3188 for (Index
= 0; Index
< 3; Index
++) {
3189 if (pNode
[Index
] != NULL
) {
3190 delete pNode
[Index
];
3193 if (VarIdStr
[Index
] != NULL
) {
3194 delete[] VarIdStr
[Index
];
3195 VarIdStr
[Index
] = NULL
;
3201 CVfrQuestionDB::RegisterRefQuestion (
3203 IN CHAR8
*BaseVarId
,
3204 IN OUT EFI_QUESTION_ID
&QuestionId
3207 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3209 CHAR8
*VarIdStr
[4] = {NULL
, };
3212 if (BaseVarId
== NULL
&& Name
== NULL
) {
3216 if (BaseVarId
!= NULL
) {
3217 Len
= strlen (BaseVarId
);
3219 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3220 if (VarIdStr
[0] != NULL
) {
3221 strcpy (VarIdStr
[0], BaseVarId
);
3222 strcat (VarIdStr
[0], ".QuestionId");
3224 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3225 if (VarIdStr
[1] != NULL
) {
3226 strcpy (VarIdStr
[1], BaseVarId
);
3227 strcat (VarIdStr
[1], ".FormId");
3229 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3230 if (VarIdStr
[2] != NULL
) {
3231 strcpy (VarIdStr
[2], BaseVarId
);
3232 strcat (VarIdStr
[2], ".FormSetGuid");
3234 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3235 if (VarIdStr
[3] != NULL
) {
3236 strcpy (VarIdStr
[3], BaseVarId
);
3237 strcat (VarIdStr
[3], ".DevicePath");
3240 Len
= strlen (Name
);
3242 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3243 if (VarIdStr
[0] != NULL
) {
3244 strcpy (VarIdStr
[0], Name
);
3245 strcat (VarIdStr
[0], ".QuestionId");
3247 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3248 if (VarIdStr
[1] != NULL
) {
3249 strcpy (VarIdStr
[1], Name
);
3250 strcat (VarIdStr
[1], ".FormId");
3252 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3253 if (VarIdStr
[2] != NULL
) {
3254 strcpy (VarIdStr
[2], Name
);
3255 strcat (VarIdStr
[2], ".FormSetGuid");
3257 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3258 if (VarIdStr
[3] != NULL
) {
3259 strcpy (VarIdStr
[3], Name
);
3260 strcat (VarIdStr
[3], ".DevicePath");
3264 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3267 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3270 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3273 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3277 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3278 QuestionId
= GetFreeQuestionId ();
3280 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3283 MarkQuestionIdUsed (QuestionId
);
3286 pNode
[0]->mQuestionId
= QuestionId
;
3287 pNode
[1]->mQuestionId
= QuestionId
;
3288 pNode
[2]->mQuestionId
= QuestionId
;
3289 pNode
[3]->mQuestionId
= QuestionId
;
3290 pNode
[0]->mQtype
= QUESTION_REF
;
3291 pNode
[1]->mQtype
= QUESTION_REF
;
3292 pNode
[2]->mQtype
= QUESTION_REF
;
3293 pNode
[3]->mQtype
= QUESTION_REF
;
3294 pNode
[0]->mNext
= pNode
[1];
3295 pNode
[1]->mNext
= pNode
[2];
3296 pNode
[2]->mNext
= pNode
[3];
3297 pNode
[3]->mNext
= mQuestionList
;
3298 mQuestionList
= pNode
[0];
3300 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3301 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3302 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3303 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3308 for (Index
= 0; Index
< 4; Index
++) {
3309 if (pNode
[Index
] != NULL
) {
3310 delete pNode
[Index
];
3313 if (VarIdStr
[Index
] != NULL
) {
3314 delete VarIdStr
[Index
];
3320 CVfrQuestionDB::UpdateQuestionId (
3321 IN EFI_QUESTION_ID QId
,
3322 IN EFI_QUESTION_ID NewQId
3325 SVfrQuestionNode
*pNode
= NULL
;
3327 if (QId
== NewQId
) {
3329 return VFR_RETURN_SUCCESS
;
3332 if (ChekQuestionIdFree (NewQId
) == FALSE
) {
3333 return VFR_RETURN_REDEFINED
;
3336 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3337 if (pNode
->mQuestionId
== QId
) {
3342 if (pNode
== NULL
) {
3343 return VFR_RETURN_UNDEFINED
;
3346 MarkQuestionIdUnused (QId
);
3347 pNode
->mQuestionId
= NewQId
;
3348 MarkQuestionIdUsed (NewQId
);
3350 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3352 return VFR_RETURN_SUCCESS
;
3356 CVfrQuestionDB::GetQuestionId (
3359 OUT EFI_QUESTION_ID
&QuestionId
,
3360 OUT UINT32
&BitMask
,
3361 OUT EFI_QUESION_TYPE
*QType
3364 SVfrQuestionNode
*pNode
;
3366 QuestionId
= EFI_QUESTION_ID_INVALID
;
3367 BitMask
= 0x00000000;
3368 if (QType
!= NULL
) {
3369 *QType
= QUESTION_NORMAL
;
3372 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3376 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3378 if (strcmp (pNode
->mName
, Name
) != 0) {
3383 if (VarIdStr
!= NULL
) {
3384 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3389 QuestionId
= pNode
->mQuestionId
;
3390 BitMask
= pNode
->mBitMask
;
3391 if (QType
!= NULL
) {
3392 *QType
= pNode
->mQtype
;
3401 CVfrQuestionDB::FindQuestion (
3402 IN EFI_QUESTION_ID QuestionId
3405 SVfrQuestionNode
*pNode
;
3407 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3408 return VFR_RETURN_INVALID_PARAMETER
;
3411 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3412 if (pNode
->mQuestionId
== QuestionId
) {
3413 return VFR_RETURN_SUCCESS
;
3417 return VFR_RETURN_UNDEFINED
;
3421 CVfrQuestionDB::FindQuestion (
3425 SVfrQuestionNode
*pNode
;
3428 return VFR_RETURN_FATAL_ERROR
;
3431 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3432 if (strcmp (pNode
->mName
, Name
) == 0) {
3433 return VFR_RETURN_SUCCESS
;
3437 return VFR_RETURN_UNDEFINED
;
3440 CVfrStringDB::CVfrStringDB ()
3442 mStringFileName
= NULL
;
3445 CVfrStringDB::~CVfrStringDB ()
3447 if (mStringFileName
!= NULL
) {
3448 delete[] mStringFileName
;
3450 mStringFileName
= NULL
;
3455 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3459 if (StringFileName
== NULL
) {
3463 if (mStringFileName
!= NULL
) {
3464 delete[] mStringFileName
;
3467 FileLen
= strlen (StringFileName
) + 1;
3468 mStringFileName
= new CHAR8
[FileLen
];
3469 if (mStringFileName
== NULL
) {
3473 strcpy (mStringFileName
, StringFileName
);
3474 mStringFileName
[FileLen
- 1] = '\0';
3479 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3480 from a set of supported languages.
3482 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3483 contains a set of language codes.
3484 @param[in] Language A variable that contains pointers to Null-terminated
3485 ASCII strings that contain one language codes.
3487 @retval FALSE The best matching language could not be found in SupportedLanguages.
3488 @retval TRUE The best matching language could be found in SupportedLanguages.
3492 CVfrStringDB::GetBestLanguage (
3493 IN CONST CHAR8
*SupportedLanguages
,
3497 UINTN CompareLength
;
3498 UINTN LanguageLength
;
3499 CONST CHAR8
*Supported
;
3501 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3506 // Determine the length of the first RFC 4646 language code in Language
3508 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3511 // Trim back the length of Language used until it is empty
3513 while (LanguageLength
> 0) {
3515 // Loop through all language codes in SupportedLanguages
3517 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3519 // Skip ';' characters in Supported
3521 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3523 // Determine the length of the next language code in Supported
3525 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3527 // If Language is longer than the Supported, then skip to the next language
3529 if (LanguageLength
> CompareLength
) {
3534 // See if the first LanguageLength characters in Supported match Language
3536 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3542 // Trim Language from the right to the next '-' character
3544 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3548 // No matches were found
3555 CVfrStringDB::GetVarStoreNameFormStringId (
3556 IN EFI_STRING_ID StringId
3559 FILE *pInFile
= NULL
;
3564 CHAR16
*UnicodeString
;
3565 CHAR8
*VarStoreName
= NULL
;
3569 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3571 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3573 if (mStringFileName
== NULL
) {
3577 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3584 fseek (pInFile
, 0, SEEK_END
);
3585 Length
= ftell (pInFile
);
3586 fseek (pInFile
, 0, SEEK_SET
);
3591 StringPtr
= new UINT8
[Length
];
3592 if (StringPtr
== NULL
) {
3596 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3599 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3601 // Check the String package.
3603 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3609 // Search the language, get best language base on RFC 4647 matching algorithm.
3611 Current
= StringPtr
;
3612 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3613 Current
+= PkgHeader
->Header
.Length
;
3614 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3616 // If can't find string package base on language, just return the first string package.
3618 if (Current
- StringPtr
>= Length
) {
3619 Current
= StringPtr
;
3620 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3625 Current
+= PkgHeader
->HdrSize
;
3627 // Find the string block according the stringId.
3629 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3630 if (Status
!= EFI_SUCCESS
) {
3636 // Get varstore name according the string type.
3638 switch (BlockType
) {
3639 case EFI_HII_SIBT_STRING_SCSU
:
3640 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3641 case EFI_HII_SIBT_STRINGS_SCSU
:
3642 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3643 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3644 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3645 strcpy (VarStoreName
, StringName
);
3647 case EFI_HII_SIBT_STRING_UCS2
:
3648 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3649 case EFI_HII_SIBT_STRINGS_UCS2
:
3650 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3651 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3652 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3653 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3654 VarStoreName
= DestTmp
;
3655 while (*UnicodeString
!= '\0') {
3656 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3666 return VarStoreName
;
3670 CVfrStringDB::FindStringBlock (
3671 IN UINT8
*StringData
,
3672 IN EFI_STRING_ID StringId
,
3673 OUT UINT32
*StringTextOffset
,
3674 OUT UINT8
*BlockType
3678 EFI_STRING_ID CurrentStringId
;
3681 UINT8
*StringTextPtr
;
3686 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3690 CurrentStringId
= 1;
3693 // Parse the string blocks to get the string text and font.
3695 BlockHdr
= StringData
;
3698 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3699 switch (*BlockHdr
) {
3700 case EFI_HII_SIBT_STRING_SCSU
:
3701 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3702 StringTextPtr
= BlockHdr
+ Offset
;
3703 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3707 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3708 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3709 StringTextPtr
= BlockHdr
+ Offset
;
3710 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3714 case EFI_HII_SIBT_STRINGS_SCSU
:
3715 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3716 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3717 BlockSize
+= StringTextPtr
- BlockHdr
;
3719 for (Index
= 0; Index
< StringCount
; Index
++) {
3720 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3721 if (CurrentStringId
== StringId
) {
3722 *BlockType
= *BlockHdr
;
3723 *StringTextOffset
= StringTextPtr
- StringData
;
3726 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3731 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3734 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3737 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3738 BlockSize
+= StringTextPtr
- BlockHdr
;
3740 for (Index
= 0; Index
< StringCount
; Index
++) {
3741 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3742 if (CurrentStringId
== StringId
) {
3743 *BlockType
= *BlockHdr
;
3744 *StringTextOffset
= StringTextPtr
- StringData
;
3747 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3752 case EFI_HII_SIBT_STRING_UCS2
:
3753 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3754 StringTextPtr
= BlockHdr
+ Offset
;
3756 // Use StringSize to store the size of the specified string, including the NULL
3759 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3760 BlockSize
+= Offset
+ StringSize
;
3764 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3765 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3766 StringTextPtr
= BlockHdr
+ Offset
;
3768 // Use StrSize to store the size of the specified string, including the NULL
3771 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3772 BlockSize
+= Offset
+ StringSize
;
3776 case EFI_HII_SIBT_STRINGS_UCS2
:
3777 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3778 StringTextPtr
= BlockHdr
+ Offset
;
3779 BlockSize
+= Offset
;
3780 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3781 for (Index
= 0; Index
< StringCount
; Index
++) {
3782 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3783 BlockSize
+= StringSize
;
3784 if (CurrentStringId
== StringId
) {
3785 *BlockType
= *BlockHdr
;
3786 *StringTextOffset
= StringTextPtr
- StringData
;
3789 StringTextPtr
= StringTextPtr
+ StringSize
;
3794 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3795 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3796 StringTextPtr
= BlockHdr
+ Offset
;
3797 BlockSize
+= Offset
;
3800 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3803 for (Index
= 0; Index
< StringCount
; Index
++) {
3804 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3805 BlockSize
+= StringSize
;
3806 if (CurrentStringId
== StringId
) {
3807 *BlockType
= *BlockHdr
;
3808 *StringTextOffset
= StringTextPtr
- StringData
;
3811 StringTextPtr
= StringTextPtr
+ StringSize
;
3816 case EFI_HII_SIBT_DUPLICATE
:
3817 if (CurrentStringId
== StringId
) {
3819 // Incoming StringId is an id of a duplicate string block.
3820 // Update the StringId to be the previous string block.
3821 // Go back to the header of string block to search.
3825 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3826 sizeof (EFI_STRING_ID
)
3828 CurrentStringId
= 1;
3831 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3836 case EFI_HII_SIBT_SKIP1
:
3837 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3838 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3839 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3842 case EFI_HII_SIBT_SKIP2
:
3843 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3844 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3845 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3848 case EFI_HII_SIBT_EXT1
:
3851 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3854 BlockSize
+= Length8
;
3857 case EFI_HII_SIBT_EXT2
:
3858 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3859 BlockSize
+= Ext2
.Length
;
3862 case EFI_HII_SIBT_EXT4
:
3865 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3869 BlockSize
+= Length32
;
3876 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3877 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3878 *BlockType
= *BlockHdr
;
3880 if (StringId
== CurrentStringId
- 1) {
3882 // if only one skip item, return EFI_NOT_FOUND.
3884 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3885 return EFI_NOT_FOUND
;
3891 if (StringId
< CurrentStringId
- 1) {
3892 return EFI_NOT_FOUND
;
3895 BlockHdr
= StringData
+ BlockSize
;
3898 return EFI_NOT_FOUND
;
3902 CVfrStringDB::GetUnicodeStringTextSize (
3909 StringSize
= sizeof (CHAR16
);
3910 StringPtr
= (UINT16
*)StringSrc
;
3911 while (*StringPtr
++ != L
'\0') {
3912 StringSize
+= sizeof (CHAR16
);
3918 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3919 CVfrDefaultStore gCVfrDefaultStore
;
3920 CVfrDataStorage gCVfrDataStorage
;