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.
18 #include "CommonLib.h"
19 #include "VfrUtilityLib.h"
20 #include "VfrFormPkg.h"
23 CVfrBinaryOutput::WriteLine (
26 IN CONST CHAR8
*LineHeader
,
33 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
37 for (Index
= 0; Index
< BlkSize
; Index
++) {
38 if ((Index
% LineBytes
) == 0) {
39 fprintf (pFile
, "\n%s", LineHeader
);
41 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
46 CVfrBinaryOutput::WriteEnd (
49 IN CONST CHAR8
*LineHeader
,
56 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
60 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
61 if ((Index
% LineBytes
) == 0) {
62 fprintf (pFile
, "\n%s", LineHeader
);
64 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
67 if ((Index
% LineBytes
) == 0) {
68 fprintf (pFile
, "\n%s", LineHeader
);
70 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
73 SConfigInfo::SConfigInfo (
77 IN EFI_IFR_TYPE_VALUE Value
82 mWidth
= (UINT16
)Width
;
83 mValue
= new UINT8
[mWidth
];
89 case EFI_IFR_TYPE_NUM_SIZE_8
:
90 memcpy (mValue
, &Value
.u8
, mWidth
);
92 case EFI_IFR_TYPE_NUM_SIZE_16
:
93 memcpy (mValue
, &Value
.u16
, mWidth
);
95 case EFI_IFR_TYPE_NUM_SIZE_32
:
96 memcpy (mValue
, &Value
.u32
, mWidth
);
98 case EFI_IFR_TYPE_NUM_SIZE_64
:
99 memcpy (mValue
, &Value
.u64
, mWidth
);
101 case EFI_IFR_TYPE_BOOLEAN
:
102 memcpy (mValue
, &Value
.b
, mWidth
);
104 case EFI_IFR_TYPE_TIME
:
105 memcpy (mValue
, &Value
.time
, mWidth
);
107 case EFI_IFR_TYPE_DATE
:
108 memcpy (mValue
, &Value
.date
, mWidth
);
110 case EFI_IFR_TYPE_STRING
:
111 memcpy (mValue
, &Value
.string
, mWidth
);
113 case EFI_IFR_TYPE_BUFFER
:
114 memcpy (mValue
, &Value
.u8
, mWidth
);
117 case EFI_IFR_TYPE_OTHER
:
122 SConfigInfo::~SConfigInfo (
126 ARRAY_SAFE_FREE (mValue
);
129 SConfigItem::SConfigItem (
142 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
143 strcpy (mName
, Name
);
148 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
149 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
154 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
160 SConfigItem::SConfigItem (
167 IN EFI_IFR_TYPE_VALUE Value
177 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
178 strcpy (mName
, Name
);
183 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
184 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
189 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
194 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
197 SConfigItem::~SConfigItem (
203 ARRAY_SAFE_FREE (mName
);
204 ARRAY_SAFE_FREE (mGuid
);
205 ARRAY_SAFE_FREE (mId
);
206 while (mInfoStrList
!= NULL
) {
208 mInfoStrList
= mInfoStrList
->mNext
;
210 BUFFER_SAFE_FREE (Info
);
215 CVfrBufferConfig::Register (
223 if (Select (Name
, Guid
) == 0) {
227 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
231 if (mItemListHead
== NULL
) {
232 mItemListHead
= pNew
;
233 mItemListTail
= pNew
;
235 mItemListTail
->mNext
= pNew
;
236 mItemListTail
= pNew
;
244 CVfrBufferConfig::Open (
248 mItemListPos
= mItemListHead
;
252 CVfrBufferConfig::Eof(
256 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
260 CVfrBufferConfig::Select (
268 if (Name
== NULL
|| Guid
== NULL
) {
269 mItemListPos
= mItemListHead
;
272 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
273 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
278 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
281 } else if (p
->mId
!= NULL
) {
294 CVfrBufferConfig::Write (
302 IN EFI_IFR_TYPE_VALUE Value
309 if ((Ret
= Select (Name
, Guid
)) != 0) {
315 if (Select (Name
, Guid
, Id
) != 0) {
316 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
319 if (mItemListHead
== NULL
) {
320 mItemListHead
= pItem
;
321 mItemListTail
= pItem
;
323 mItemListTail
->mNext
= pItem
;
324 mItemListTail
= pItem
;
326 mItemListPos
= pItem
;
328 // tranverse the list to find out if there's already the value for the same offset
329 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
330 if (pInfo
->mOffset
== Offset
) {
334 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
337 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
338 mItemListPos
->mInfoStrList
= pInfo
;
343 if (mItemListHead
== mItemListPos
) {
344 mItemListHead
= mItemListPos
->mNext
;
349 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
352 pItem
->mNext
= mItemListPos
->mNext
;
353 if (mItemListTail
== mItemListPos
) {
354 mItemListTail
= pItem
;
357 mItemListPos
= pItem
->mNext
;
360 case 'i' : // set info
361 if (mItemListPos
->mId
!= NULL
) {
362 delete mItemListPos
->mId
;
364 mItemListPos
->mId
= NULL
;
366 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
369 strcpy (mItemListPos
->mId
, Id
);
382 CVfrBufferConfig::Close (
389 #define BYTES_PRE_LINE 0x10
392 CVfrBufferConfig::OutputCFile (
397 CVfrBinaryOutput Output
;
406 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
407 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
410 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
412 TotalLen
= sizeof (UINT32
);
413 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
414 TotalLen
+= sizeof (UINT16
) * 2;
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
418 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
419 fprintf (pFile
, "\n");
420 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
421 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
423 fprintf (pFile
, "\n};\n");
426 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
427 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
428 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
430 TotalLen
= sizeof (UINT32
);
431 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
432 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
436 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
437 fprintf (pFile
, "\n");
438 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
439 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
440 if (Info
->mNext
== NULL
) {
441 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
443 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
446 fprintf (pFile
, "\n};\n");
451 CVfrBufferConfig::CVfrBufferConfig (
455 mItemListHead
= NULL
;
456 mItemListTail
= NULL
;
460 CVfrBufferConfig::~CVfrBufferConfig (
466 while (mItemListHead
!= NULL
) {
468 mItemListHead
= mItemListHead
->mNext
;
472 mItemListHead
= NULL
;
473 mItemListTail
= NULL
;
477 CVfrBufferConfig gCVfrBufferConfig
;
480 CONST CHAR8
*mTypeName
;
484 } gInternalTypesTable
[] = {
485 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
486 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
487 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
488 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
489 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
490 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
491 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
492 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
493 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
494 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
505 if (TypeName
== NULL
) {
509 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
510 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
527 while (*Str
&& *Str
== ' ') {
530 while (*Str
&& *Str
== '0') {
533 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
550 Str
= TrimHex (Str
, &IsHex
);
551 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
553 // BUG: does not handle overflow here
555 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
557 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
558 Value
+= (c
- 'a' + 10);
560 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
561 Value
+= (c
- 'A' + 10);
563 if (c
>= '0' && c
<= '9') {
572 CVfrVarDataTypeDB::RegisterNewType (
576 New
->mNext
= mDataTypeList
;
581 CVfrVarDataTypeDB::ExtractStructTypeName (
587 return VFR_RETURN_FATAL_ERROR
;
590 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
596 if (*VarStr
== '.') {
600 return VFR_RETURN_SUCCESS
;
604 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
611 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
613 ArrayIdx
= INVALID_ARRAY_INDEX
;
616 return VFR_RETURN_FATAL_ERROR
;
619 while((*VarStr
!= '\0') &&
633 return VFR_RETURN_SUCCESS
;
636 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
637 ArrayStr
[Idx
] = *VarStr
;
639 ArrayStr
[Idx
] = '\0';
641 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
642 return VFR_RETURN_DATA_STRING_ERROR
;
644 ArrayIdx
= _STR2U32 (ArrayStr
);
645 if (*VarStr
== ']') {
648 if (*VarStr
== '.') {
651 return VFR_RETURN_SUCCESS
;
653 return VFR_RETURN_DATA_STRING_ERROR
;
656 return VFR_RETURN_SUCCESS
;
660 CVfrVarDataTypeDB::GetTypeField (
661 IN CONST CHAR8
*FName
,
662 IN SVfrDataType
*Type
,
663 OUT SVfrDataField
*&Field
666 SVfrDataField
*pField
= NULL
;
668 if ((FName
== NULL
) || (Type
== NULL
)) {
669 return VFR_RETURN_FATAL_ERROR
;
672 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
674 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
675 // add code to adjust it.
677 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
678 if (strcmp (FName
, "Hour") == 0) {
680 } else if (strcmp (FName
, "Minute") == 0) {
682 } else if (strcmp (FName
, "Second") == 0) {
687 if (strcmp (pField
->mFieldName
, FName
) == 0) {
689 return VFR_RETURN_SUCCESS
;
693 return VFR_RETURN_UNDEFINED
;
697 CVfrVarDataTypeDB::GetFieldOffset (
698 IN SVfrDataField
*Field
,
704 return VFR_RETURN_FATAL_ERROR
;
708 // Framework Vfr file Array Index is from 1.
709 // But Uefi Vfr file Array Index is from 0.
711 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
713 return VFR_RETURN_ERROR_ARRARY_NUM
;
715 ArrayIdx
= ArrayIdx
- 1;
718 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
719 return VFR_RETURN_ERROR_ARRARY_NUM
;
723 // Be compatible with the current usage
724 // If ArraryIdx is not specified, the first one is used.
726 // if ArrayNum is larger than zero, ArraryIdx must be specified.
728 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
729 // return VFR_RETURN_ERROR_ARRARY_NUM;
733 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
734 return VFR_RETURN_SUCCESS
;
738 CVfrVarDataTypeDB::GetFieldWidth (
739 IN SVfrDataField
*Field
746 return Field
->mFieldType
->mType
;
750 CVfrVarDataTypeDB::GetFieldSize (
751 IN SVfrDataField
*Field
,
756 return VFR_RETURN_FATAL_ERROR
;
759 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
760 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
762 return Field
->mFieldType
->mTotalSize
;
767 CVfrVarDataTypeDB::InternalTypesListInit (
771 SVfrDataType
*New
= NULL
;
774 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
775 New
= new SVfrDataType
;
777 strcpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
);
778 New
->mType
= gInternalTypesTable
[Index
].mType
;
779 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
780 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
781 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
782 SVfrDataField
*pYearField
= new SVfrDataField
;
783 SVfrDataField
*pMonthField
= new SVfrDataField
;
784 SVfrDataField
*pDayField
= new SVfrDataField
;
786 strcpy (pYearField
->mFieldName
, "Year");
787 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
788 pYearField
->mOffset
= 0;
789 pYearField
->mNext
= pMonthField
;
790 pYearField
->mArrayNum
= 0;
792 strcpy (pMonthField
->mFieldName
, "Month");
793 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
794 pMonthField
->mOffset
= 2;
795 pMonthField
->mNext
= pDayField
;
796 pMonthField
->mArrayNum
= 0;
798 strcpy (pDayField
->mFieldName
, "Day");
799 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
800 pDayField
->mOffset
= 3;
801 pDayField
->mNext
= NULL
;
802 pDayField
->mArrayNum
= 0;
804 New
->mMembers
= pYearField
;
805 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
806 SVfrDataField
*pHoursField
= new SVfrDataField
;
807 SVfrDataField
*pMinutesField
= new SVfrDataField
;
808 SVfrDataField
*pSecondsField
= new SVfrDataField
;
810 strcpy (pHoursField
->mFieldName
, "Hours");
811 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
812 pHoursField
->mOffset
= 0;
813 pHoursField
->mNext
= pMinutesField
;
814 pHoursField
->mArrayNum
= 0;
816 strcpy (pMinutesField
->mFieldName
, "Minutes");
817 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
818 pMinutesField
->mOffset
= 1;
819 pMinutesField
->mNext
= pSecondsField
;
820 pMinutesField
->mArrayNum
= 0;
822 strcpy (pSecondsField
->mFieldName
, "Seconds");
823 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
824 pSecondsField
->mOffset
= 2;
825 pSecondsField
->mNext
= NULL
;
826 pSecondsField
->mArrayNum
= 0;
828 New
->mMembers
= pHoursField
;
829 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
830 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
831 SVfrDataField
*pFormIdField
= new SVfrDataField
;
832 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
833 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
835 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
836 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
837 pQuestionIdField
->mOffset
= 0;
838 pQuestionIdField
->mNext
= pFormIdField
;
839 pQuestionIdField
->mArrayNum
= 0;
841 strcpy (pFormIdField
->mFieldName
, "FormId");
842 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
843 pFormIdField
->mOffset
= 2;
844 pFormIdField
->mNext
= pFormSetGuidField
;
845 pFormIdField
->mArrayNum
= 0;
847 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
848 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
849 pFormSetGuidField
->mOffset
= 4;
850 pFormSetGuidField
->mNext
= pDevicePathField
;
851 pFormSetGuidField
->mArrayNum
= 0;
853 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
854 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
855 pDevicePathField
->mOffset
= 20;
856 pDevicePathField
->mNext
= NULL
;
857 pDevicePathField
->mArrayNum
= 0;
859 New
->mMembers
= pQuestionIdField
;
861 New
->mMembers
= NULL
;
864 RegisterNewType (New
);
870 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
874 mDataTypeList
= NULL
;
876 mCurrDataField
= NULL
;
877 mPackAlign
= DEFAULT_PACK_ALIGN
;
879 mFirstNewDataTypeName
= NULL
;
881 InternalTypesListInit ();
884 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
889 SVfrDataField
*pField
;
890 SVfrPackStackNode
*pPack
;
892 if (mNewDataType
!= NULL
) {
896 while (mDataTypeList
!= NULL
) {
897 pType
= mDataTypeList
;
898 mDataTypeList
= mDataTypeList
->mNext
;
899 while(pType
->mMembers
!= NULL
) {
900 pField
= pType
->mMembers
;
901 pType
->mMembers
= pType
->mMembers
->mNext
;
907 while (mPackStack
!= NULL
) {
909 mPackStack
= mPackStack
->mNext
;
915 CVfrVarDataTypeDB::Pack (
918 IN CHAR8
*Identifier
,
923 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
925 if (Action
& VFR_PACK_SHOW
) {
926 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
927 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
930 if (Action
& VFR_PACK_PUSH
) {
931 SVfrPackStackNode
*pNew
= NULL
;
933 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
934 return VFR_RETURN_FATAL_ERROR
;
936 pNew
->mNext
= mPackStack
;
940 if (Action
& VFR_PACK_POP
) {
941 SVfrPackStackNode
*pNode
= NULL
;
943 if (mPackStack
== NULL
) {
944 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
947 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
948 if (pNode
->Match (Identifier
) == TRUE
) {
949 mPackAlign
= pNode
->mNumber
;
950 mPackStack
= pNode
->mNext
;
955 if (Action
& VFR_PACK_ASSIGN
) {
956 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
957 if ((PackAlign
== 0) || (PackAlign
> 16)) {
958 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
960 mPackAlign
= PackAlign
;
964 return VFR_RETURN_SUCCESS
;
968 CVfrVarDataTypeDB::DeclareDataTypeBegin (
972 SVfrDataType
*pNewType
= NULL
;
974 pNewType
= new SVfrDataType
;
975 pNewType
->mTypeName
[0] = '\0';
976 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
977 pNewType
->mAlign
= DEFAULT_ALIGN
;
978 pNewType
->mTotalSize
= 0;
979 pNewType
->mMembers
= NULL
;
980 pNewType
->mNext
= NULL
;
982 mNewDataType
= pNewType
;
986 CVfrVarDataTypeDB::SetNewTypeName (
992 if (mNewDataType
== NULL
) {
993 return VFR_RETURN_ERROR_SKIPED
;
995 if (TypeName
== NULL
) {
996 return VFR_RETURN_FATAL_ERROR
;
998 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
999 return VFR_RETURN_INVALID_PARAMETER
;
1002 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1003 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1004 return VFR_RETURN_REDEFINED
;
1008 strcpy(mNewDataType
->mTypeName
, TypeName
);
1009 return VFR_RETURN_SUCCESS
;
1013 CVfrVarDataTypeDB::DataTypeAddField (
1014 IN CHAR8
*FieldName
,
1017 IN BOOLEAN FieldInUnion
1020 SVfrDataField
*pNewField
= NULL
;
1021 SVfrDataType
*pFieldType
= NULL
;
1022 SVfrDataField
*pTmp
;
1024 UINT32 MaxDataTypeSize
;
1026 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1027 MaxDataTypeSize
= mNewDataType
->mTotalSize
;
1029 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1030 return VFR_RETURN_INVALID_PARAMETER
;
1033 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1034 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1035 return VFR_RETURN_REDEFINED
;
1039 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1041 if ((pNewField
= new SVfrDataField
) == NULL
) {
1042 return VFR_RETURN_OUT_FOR_RESOURCES
;
1044 strcpy (pNewField
->mFieldName
, FieldName
);
1045 pNewField
->mFieldType
= pFieldType
;
1046 pNewField
->mArrayNum
= ArrayNum
;
1047 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1048 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1050 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1052 if (mNewDataType
->mMembers
== NULL
) {
1053 mNewDataType
->mMembers
= pNewField
;
1054 pNewField
->mNext
= NULL
;
1056 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1058 pTmp
->mNext
= pNewField
;
1059 pNewField
->mNext
= NULL
;
1062 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1065 if (MaxDataTypeSize
< pNewField
->mFieldType
->mTotalSize
) {
1066 mNewDataType
->mTotalSize
= pNewField
->mFieldType
->mTotalSize
;
1068 pNewField
->mOffset
= 0;
1070 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1073 return VFR_RETURN_SUCCESS
;
1077 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1081 if (mNewDataType
->mTypeName
[0] == '\0') {
1085 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1086 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1089 RegisterNewType (mNewDataType
);
1090 if (mFirstNewDataTypeName
== NULL
) {
1091 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1094 mNewDataType
= NULL
;
1098 CVfrVarDataTypeDB::GetDataType (
1100 OUT SVfrDataType
**DataType
1103 SVfrDataType
*pDataType
= NULL
;
1105 if (TypeName
== NULL
) {
1106 return VFR_RETURN_ERROR_SKIPED
;
1109 if (DataType
== NULL
) {
1110 return VFR_RETURN_FATAL_ERROR
;
1115 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1116 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1117 *DataType
= pDataType
;
1118 return VFR_RETURN_SUCCESS
;
1122 return VFR_RETURN_UNDEFINED
;
1126 CVfrVarDataTypeDB::GetDataTypeSize (
1131 SVfrDataType
*pDataType
= NULL
;
1134 return VFR_RETURN_FATAL_ERROR
;
1138 DataType
= DataType
& 0x0F;
1141 // For user defined data type, the size can't be got by this function.
1143 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1144 return VFR_RETURN_SUCCESS
;
1147 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1148 if (DataType
== pDataType
->mType
) {
1149 *Size
= pDataType
->mTotalSize
;
1150 return VFR_RETURN_SUCCESS
;
1154 return VFR_RETURN_UNDEFINED
;
1158 CVfrVarDataTypeDB::GetDataTypeSize (
1163 SVfrDataType
*pDataType
= NULL
;
1166 return VFR_RETURN_FATAL_ERROR
;
1171 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1172 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1173 *Size
= pDataType
->mTotalSize
;
1174 return VFR_RETURN_SUCCESS
;
1178 return VFR_RETURN_UNDEFINED
;
1182 CVfrVarDataTypeDB::GetDataFieldInfo (
1189 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1190 UINT32 ArrayIdx
, Tmp
;
1191 SVfrDataType
*pType
= NULL
;
1192 SVfrDataField
*pField
= NULL
;
1195 Type
= EFI_IFR_TYPE_OTHER
;
1198 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1199 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1202 // if it is not struct data type
1204 Type
= pType
->mType
;
1205 Size
= pType
->mTotalSize
;
1207 while (*VarStr
!= '\0') {
1208 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1209 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1210 pType
= pField
->mFieldType
;
1211 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1212 Offset
= (UINT16
) (Offset
+ Tmp
);
1213 Type
= GetFieldWidth (pField
);
1214 Size
= GetFieldSize (pField
, ArrayIdx
);
1216 return VFR_RETURN_SUCCESS
;
1220 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1221 OUT CHAR8
***NameList
,
1222 OUT UINT32
*ListSize
1226 SVfrDataType
*pType
;
1228 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1229 return VFR_RETURN_FATAL_ERROR
;
1235 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1236 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1241 if (*ListSize
== 0) {
1242 return VFR_RETURN_SUCCESS
;
1245 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1247 return VFR_RETURN_OUT_FOR_RESOURCES
;
1250 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1251 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1252 (*NameList
)[Index
] = pType
->mTypeName
;
1255 return VFR_RETURN_SUCCESS
;
1259 CVfrVarDataTypeDB::IsTypeNameDefined (
1263 SVfrDataType
*pType
;
1265 if (TypeName
== NULL
) {
1269 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1270 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1279 CVfrVarDataTypeDB::Dump (
1283 SVfrDataType
*pTNode
;
1284 SVfrDataField
*pFNode
;
1286 fprintf (File
, "\n\n***************************************************************\n");
1287 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1288 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1289 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1290 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1291 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1292 if (pFNode
->mArrayNum
> 0) {
1293 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1294 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1296 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1297 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1300 fprintf (File
, "\t\t};\n");
1301 fprintf (File
, "---------------------------------------------------------------\n");
1303 fprintf (File
, "***************************************************************\n");
1306 #ifdef CVFR_VARDATATYPEDB_DEBUG
1308 CVfrVarDataTypeDB::ParserDB (
1312 SVfrDataType
*pTNode
;
1313 SVfrDataField
*pFNode
;
1315 printf ("***************************************************************\n");
1316 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1317 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1318 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1319 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1320 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1321 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1323 printf ("\t\t};\n");
1324 printf ("---------------------------------------------------------------\n");
1326 printf ("***************************************************************\n");
1330 SVfrVarStorageNode::SVfrVarStorageNode (
1332 IN CHAR8
*StoreName
,
1333 IN EFI_VARSTORE_ID VarStoreId
,
1334 IN EFI_STRING_ID VarName
,
1342 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1344 if (StoreName
!= NULL
) {
1345 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1346 strcpy (mVarStoreName
, StoreName
);
1348 mVarStoreName
= NULL
;
1351 mVarStoreId
= VarStoreId
;
1352 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1353 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1354 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1355 mAssignedFlag
= Flag
;
1358 SVfrVarStorageNode::SVfrVarStorageNode (
1360 IN CHAR8
*StoreName
,
1361 IN EFI_VARSTORE_ID VarStoreId
,
1362 IN SVfrDataType
*DataType
,
1369 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1371 if (StoreName
!= NULL
) {
1372 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1373 strcpy (mVarStoreName
, StoreName
);
1375 mVarStoreName
= NULL
;
1378 mVarStoreId
= VarStoreId
;
1379 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1380 mStorageInfo
.mDataType
= DataType
;
1381 mAssignedFlag
= Flag
;
1384 SVfrVarStorageNode::SVfrVarStorageNode (
1385 IN CHAR8
*StoreName
,
1386 IN EFI_VARSTORE_ID VarStoreId
1389 if (StoreName
!= NULL
) {
1390 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1391 strcpy (mVarStoreName
, StoreName
);
1393 mVarStoreName
= NULL
;
1396 mVarStoreId
= VarStoreId
;
1397 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1398 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1399 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1402 SVfrVarStorageNode::~SVfrVarStorageNode (
1406 if (mVarStoreName
!= NULL
) {
1407 delete[] mVarStoreName
;
1410 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1411 delete mStorageInfo
.mNameSpace
.mNameTable
;
1415 CVfrDataStorage::CVfrDataStorage (
1421 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1422 mFreeVarStoreIdBitMap
[Index
] = 0;
1425 // Question ID 0 is reserved.
1426 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1428 mBufferVarStoreList
= NULL
;
1429 mEfiVarStoreList
= NULL
;
1430 mNameVarStoreList
= NULL
;
1431 mCurrVarStorageNode
= NULL
;
1432 mNewVarStorageNode
= NULL
;
1433 mBufferFieldInfoListHead
= NULL
;
1434 mBufferFieldInfoListTail
= NULL
;
1437 CVfrDataStorage::~CVfrDataStorage (
1441 SVfrVarStorageNode
*pNode
;
1443 while (mBufferVarStoreList
!= NULL
) {
1444 pNode
= mBufferVarStoreList
;
1445 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1448 while (mEfiVarStoreList
!= NULL
) {
1449 pNode
= mEfiVarStoreList
;
1450 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1453 while (mNameVarStoreList
!= NULL
) {
1454 pNode
= mNameVarStoreList
;
1455 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1458 if (mNewVarStorageNode
!= NULL
) {
1459 delete mNewVarStorageNode
;
1464 CVfrDataStorage::GetFreeVarStoreId (
1465 EFI_VFR_VARSTORE_TYPE VarType
1468 UINT32 Index
, Mask
, Offset
;
1471 // Assign the different ID range for the different type VarStore to support Framework Vfr
1474 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1476 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1478 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1482 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1483 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1488 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1489 return EFI_VARSTORE_ID_INVALID
;
1492 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1493 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1494 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1495 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1499 return EFI_VARSTORE_ID_INVALID
;
1503 CVfrDataStorage::ChekVarStoreIdFree (
1504 IN EFI_VARSTORE_ID VarStoreId
1507 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1508 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1510 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1514 CVfrDataStorage::MarkVarStoreIdUsed (
1515 IN EFI_VARSTORE_ID VarStoreId
1518 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1519 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1521 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1525 CVfrDataStorage::MarkVarStoreIdUnused (
1526 IN EFI_VARSTORE_ID VarStoreId
1529 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1530 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1532 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1536 CVfrDataStorage::DeclareNameVarStoreBegin (
1537 IN CHAR8
*StoreName
,
1538 IN EFI_VARSTORE_ID VarStoreId
1541 SVfrVarStorageNode
*pNode
= NULL
;
1542 EFI_VARSTORE_ID TmpVarStoreId
;
1544 if (StoreName
== NULL
) {
1545 return VFR_RETURN_FATAL_ERROR
;
1548 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1549 return VFR_RETURN_REDEFINED
;
1552 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1553 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1555 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1556 return VFR_RETURN_VARSTOREID_REDEFINED
;
1558 MarkVarStoreIdUsed (VarStoreId
);
1561 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1562 return VFR_RETURN_UNDEFINED
;
1565 mNewVarStorageNode
= pNode
;
1567 return VFR_RETURN_SUCCESS
;
1571 CVfrDataStorage::NameTableAddItem (
1572 IN EFI_STRING_ID Item
1575 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1578 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1579 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1581 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1582 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1583 return VFR_RETURN_OUT_FOR_RESOURCES
;
1585 memcpy (NewTable
, OldTable
, TableSize
);
1586 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1589 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1590 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1592 return VFR_RETURN_SUCCESS
;
1596 CVfrDataStorage::DeclareNameVarStoreEnd (
1600 mNewVarStorageNode
->mGuid
= *Guid
;
1601 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1602 mNameVarStoreList
= mNewVarStorageNode
;
1604 mNewVarStorageNode
= NULL
;
1606 return VFR_RETURN_SUCCESS
;
1610 CVfrDataStorage::DeclareEfiVarStore (
1611 IN CHAR8
*StoreName
,
1613 IN EFI_STRING_ID NameStrId
,
1618 SVfrVarStorageNode
*pNode
;
1619 EFI_VARSTORE_ID VarStoreId
;
1621 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1622 return VFR_RETURN_FATAL_ERROR
;
1625 if (VarSize
> sizeof (UINT64
)) {
1626 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1629 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1630 return VFR_RETURN_REDEFINED
;
1633 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1634 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1635 return VFR_RETURN_OUT_FOR_RESOURCES
;
1638 pNode
->mNext
= mEfiVarStoreList
;
1639 mEfiVarStoreList
= pNode
;
1641 return VFR_RETURN_SUCCESS
;
1645 CVfrDataStorage::DeclareBufferVarStore (
1646 IN CHAR8
*StoreName
,
1648 IN CVfrVarDataTypeDB
*DataTypeDB
,
1650 IN EFI_VARSTORE_ID VarStoreId
,
1654 SVfrVarStorageNode
*pNew
= NULL
;
1655 SVfrDataType
*pDataType
= NULL
;
1656 EFI_VARSTORE_ID TempVarStoreId
;
1658 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1659 return VFR_RETURN_FATAL_ERROR
;
1662 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1663 return VFR_RETURN_REDEFINED
;
1666 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1668 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1669 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1671 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1672 return VFR_RETURN_VARSTOREID_REDEFINED
;
1674 MarkVarStoreIdUsed (VarStoreId
);
1677 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1678 return VFR_RETURN_OUT_FOR_RESOURCES
;
1681 pNew
->mNext
= mBufferVarStoreList
;
1682 mBufferVarStoreList
= pNew
;
1684 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1685 return VFR_RETURN_FATAL_ERROR
;
1688 return VFR_RETURN_SUCCESS
;
1692 CVfrDataStorage::GetVarStoreByDataType (
1693 IN CHAR8
*DataTypeName
,
1694 OUT SVfrVarStorageNode
**VarNode
,
1695 IN EFI_GUID
*VarGuid
1698 SVfrVarStorageNode
*pNode
;
1699 SVfrVarStorageNode
*MatchNode
;
1702 // Framework VFR uses Data type name as varstore name, so don't need check again.
1704 if (VfrCompatibleMode
) {
1705 return VFR_RETURN_UNDEFINED
;
1709 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1710 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1714 if ((VarGuid
!= NULL
)) {
1715 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1717 return VFR_RETURN_SUCCESS
;
1720 if (MatchNode
== NULL
) {
1724 // More than one varstores referred the same data structures.
1726 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1731 if (MatchNode
== NULL
) {
1732 return VFR_RETURN_UNDEFINED
;
1735 *VarNode
= MatchNode
;
1736 return VFR_RETURN_SUCCESS
;
1740 CVfrDataStorage::CheckGuidField (
1741 IN SVfrVarStorageNode
*pNode
,
1742 IN EFI_GUID
*StoreGuid
,
1743 IN BOOLEAN
*HasFoundOne
,
1744 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1747 if (StoreGuid
!= NULL
) {
1749 // If has guid info, compare the guid filed.
1751 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1753 // Both name and guid are same, this this varstore.
1755 mCurrVarStorageNode
= pNode
;
1756 *ReturnCode
= VFR_RETURN_SUCCESS
;
1761 // Not has Guid field, check whether this name is the only one.
1765 // The name has conflict, return name redefined.
1767 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1771 *HasFoundOne
= TRUE
;
1772 mCurrVarStorageNode
= pNode
;
1779 Base on the input store name and guid to find the varstore id.
1781 If both name and guid are inputed, base on the name and guid to
1782 found the varstore. If only name inputed, base on the name to
1783 found the varstore and go on to check whether more than one varstore
1784 has the same name. If only has found one varstore, return this
1785 varstore; if more than one varstore has same name, return varstore
1786 name redefined error. If no varstore found by varstore name, call
1787 function GetVarStoreByDataType and use inputed varstore name as
1788 data type name to search.
1791 CVfrDataStorage::GetVarStoreId (
1792 IN CHAR8
*StoreName
,
1793 OUT EFI_VARSTORE_ID
*VarStoreId
,
1794 IN EFI_GUID
*StoreGuid
1797 EFI_VFR_RETURN_CODE ReturnCode
;
1798 SVfrVarStorageNode
*pNode
;
1799 BOOLEAN HasFoundOne
= FALSE
;
1801 mCurrVarStorageNode
= NULL
;
1803 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1804 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1805 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1806 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1812 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1813 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1814 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1815 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1821 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1822 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1823 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1824 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1831 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1832 return VFR_RETURN_SUCCESS
;
1835 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1838 // Assume that Data strucutre name is used as StoreName, and check again.
1840 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1841 if (pNode
!= NULL
) {
1842 mCurrVarStorageNode
= pNode
;
1843 *VarStoreId
= pNode
->mVarStoreId
;
1850 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1851 IN EFI_VARSTORE_ID VarStoreId
,
1852 OUT CHAR8
**DataTypeName
1855 SVfrVarStorageNode
*pNode
;
1857 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1858 return VFR_RETURN_FATAL_ERROR
;
1861 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1862 if (pNode
->mVarStoreId
== VarStoreId
) {
1863 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1864 return VFR_RETURN_SUCCESS
;
1868 return VFR_RETURN_UNDEFINED
;
1871 EFI_VFR_VARSTORE_TYPE
1872 CVfrDataStorage::GetVarStoreType (
1873 IN EFI_VARSTORE_ID VarStoreId
1876 SVfrVarStorageNode
*pNode
;
1877 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1879 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1881 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1882 return VarStoreType
;
1885 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1886 if (pNode
->mVarStoreId
== VarStoreId
) {
1887 VarStoreType
= pNode
->mVarStoreType
;
1888 return VarStoreType
;
1892 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1893 if (pNode
->mVarStoreId
== VarStoreId
) {
1894 VarStoreType
= pNode
->mVarStoreType
;
1895 return VarStoreType
;
1899 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1900 if (pNode
->mVarStoreId
== VarStoreId
) {
1901 VarStoreType
= pNode
->mVarStoreType
;
1902 return VarStoreType
;
1906 return VarStoreType
;
1910 CVfrDataStorage::GetVarStoreGuid (
1911 IN EFI_VARSTORE_ID VarStoreId
1914 SVfrVarStorageNode
*pNode
;
1919 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1923 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1924 if (pNode
->mVarStoreId
== VarStoreId
) {
1925 VarGuid
= &pNode
->mGuid
;
1930 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1931 if (pNode
->mVarStoreId
== VarStoreId
) {
1932 VarGuid
= &pNode
->mGuid
;
1937 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1938 if (pNode
->mVarStoreId
== VarStoreId
) {
1939 VarGuid
= &pNode
->mGuid
;
1948 CVfrDataStorage::GetVarStoreName (
1949 IN EFI_VARSTORE_ID VarStoreId
,
1950 OUT CHAR8
**VarStoreName
1953 SVfrVarStorageNode
*pNode
;
1955 if (VarStoreName
== NULL
) {
1956 return VFR_RETURN_FATAL_ERROR
;
1959 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1960 if (pNode
->mVarStoreId
== VarStoreId
) {
1961 *VarStoreName
= pNode
->mVarStoreName
;
1962 return VFR_RETURN_SUCCESS
;
1966 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1967 if (pNode
->mVarStoreId
== VarStoreId
) {
1968 *VarStoreName
= pNode
->mVarStoreName
;
1969 return VFR_RETURN_SUCCESS
;
1973 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1974 if (pNode
->mVarStoreId
== VarStoreId
) {
1975 *VarStoreName
= pNode
->mVarStoreName
;
1976 return VFR_RETURN_SUCCESS
;
1980 *VarStoreName
= NULL
;
1981 return VFR_RETURN_UNDEFINED
;
1985 CVfrDataStorage::GetEfiVarStoreInfo (
1986 IN OUT EFI_VARSTORE_INFO
*Info
1990 return VFR_RETURN_FATAL_ERROR
;
1993 if (mCurrVarStorageNode
== NULL
) {
1994 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1997 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1998 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1999 switch (Info
->mVarTotalSize
) {
2001 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
2004 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
2007 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
2010 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2013 return VFR_RETURN_FATAL_ERROR
;
2016 return VFR_RETURN_SUCCESS
;
2020 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2021 IN EFI_VARSTORE_INFO
*Info
2024 BufferVarStoreFieldInfoNode
*pNew
;
2026 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2027 return VFR_RETURN_FATAL_ERROR
;
2030 if (mBufferFieldInfoListHead
== NULL
) {
2031 mBufferFieldInfoListHead
= pNew
;
2032 mBufferFieldInfoListTail
= pNew
;
2034 mBufferFieldInfoListTail
->mNext
= pNew
;
2035 mBufferFieldInfoListTail
= pNew
;
2038 return VFR_RETURN_SUCCESS
;
2042 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2043 IN OUT EFI_VARSTORE_INFO
*Info
2046 BufferVarStoreFieldInfoNode
*pNode
;
2048 pNode
= mBufferFieldInfoListHead
;
2049 while (pNode
!= NULL
) {
2050 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2051 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2052 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2053 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2054 return VFR_RETURN_SUCCESS
;
2056 pNode
= pNode
->mNext
;
2058 return VFR_RETURN_FATAL_ERROR
;
2062 CVfrDataStorage::GetNameVarStoreInfo (
2063 OUT EFI_VARSTORE_INFO
*Info
,
2068 return VFR_RETURN_FATAL_ERROR
;
2071 if (mCurrVarStorageNode
== NULL
) {
2072 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2076 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2078 if (VfrCompatibleMode
) {
2080 return VFR_RETURN_ERROR_ARRARY_NUM
;
2085 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2087 return VFR_RETURN_SUCCESS
;
2090 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2091 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2093 IN EFI_STRING_ID DefaultStoreNameId
,
2097 mObjBinAddr
= ObjBinAddr
;
2099 if (RefName
!= NULL
) {
2100 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2101 strcpy (mRefName
, RefName
);
2107 mDefaultId
= DefaultId
;
2108 mDefaultStoreNameId
= DefaultStoreNameId
;
2111 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2115 if (mRefName
!= NULL
) {
2120 CVfrDefaultStore::CVfrDefaultStore (
2124 mDefaultStoreList
= NULL
;
2127 CVfrDefaultStore::~CVfrDefaultStore (
2131 SVfrDefaultStoreNode
*pTmp
= NULL
;
2133 while (mDefaultStoreList
!= NULL
) {
2134 pTmp
= mDefaultStoreList
;
2135 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2141 CVfrDefaultStore::RegisterDefaultStore (
2142 IN CHAR8
*ObjBinAddr
,
2144 IN EFI_STRING_ID DefaultStoreNameId
,
2148 SVfrDefaultStoreNode
*pNode
= NULL
;
2150 if (RefName
== NULL
) {
2151 return VFR_RETURN_FATAL_ERROR
;
2154 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2155 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2156 return VFR_RETURN_REDEFINED
;
2160 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2161 return VFR_RETURN_OUT_FOR_RESOURCES
;
2164 pNode
->mNext
= mDefaultStoreList
;
2165 mDefaultStoreList
= pNode
;
2167 return VFR_RETURN_SUCCESS
;
2171 * assign new reference name or new default store name id only if
2172 * the original is invalid
2175 CVfrDefaultStore::ReRegisterDefaultStoreById (
2176 IN UINT16 DefaultId
,
2178 IN EFI_STRING_ID DefaultStoreNameId
2181 SVfrDefaultStoreNode
*pNode
= NULL
;
2183 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2184 if (pNode
->mDefaultId
== DefaultId
) {
2189 if (pNode
== NULL
) {
2190 return VFR_RETURN_UNDEFINED
;
2192 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2193 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2194 if (pNode
->mObjBinAddr
!= NULL
) {
2195 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2198 return VFR_RETURN_REDEFINED
;
2201 if (RefName
!= NULL
) {
2202 delete pNode
->mRefName
;
2203 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2204 if (pNode
->mRefName
!= NULL
) {
2205 strcpy (pNode
->mRefName
, RefName
);
2210 return VFR_RETURN_SUCCESS
;
2214 CVfrDefaultStore::DefaultIdRegistered (
2218 SVfrDefaultStoreNode
*pNode
= NULL
;
2220 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2221 if (pNode
->mDefaultId
== DefaultId
) {
2230 CVfrDefaultStore::GetDefaultId (
2232 OUT UINT16
*DefaultId
2235 SVfrDefaultStoreNode
*pTmp
= NULL
;
2237 if (DefaultId
== NULL
) {
2238 return VFR_RETURN_FATAL_ERROR
;
2241 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2242 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2243 *DefaultId
= pTmp
->mDefaultId
;
2244 return VFR_RETURN_SUCCESS
;
2248 return VFR_RETURN_UNDEFINED
;
2252 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2253 IN EFI_VARSTORE_ID DefaultId
,
2254 IN EFI_VARSTORE_INFO
&Info
,
2255 IN CHAR8
*VarStoreName
,
2256 IN EFI_GUID
*VarStoreGuid
,
2258 IN EFI_IFR_TYPE_VALUE Value
2261 SVfrDefaultStoreNode
*pNode
= NULL
;
2262 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2263 INTN Returnvalue
= 0;
2265 if (VarStoreName
== NULL
) {
2266 return VFR_RETURN_FATAL_ERROR
;
2269 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2270 if (pNode
->mDefaultId
== DefaultId
) {
2275 if (pNode
== NULL
) {
2276 return VFR_RETURN_UNDEFINED
;
2279 gCVfrBufferConfig
.Open ();
2281 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2282 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2283 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2288 gCVfrBufferConfig
.Close ();
2290 return VFR_RETURN_SUCCESS
;
2293 gCVfrBufferConfig
.Close ();
2294 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2297 SVfrRuleNode::SVfrRuleNode (
2302 if (RuleName
!= NULL
) {
2303 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2304 strcpy (mRuleName
, RuleName
);
2313 SVfrRuleNode::~SVfrRuleNode (
2317 if (mRuleName
!= NULL
) {
2322 CVfrRulesDB::CVfrRulesDB ()
2325 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2328 CVfrRulesDB::~CVfrRulesDB ()
2330 SVfrRuleNode
*pNode
;
2332 while(mRuleList
!= NULL
) {
2334 mRuleList
= mRuleList
->mNext
;
2340 CVfrRulesDB::RegisterRule (
2346 if (RuleName
== NULL
) {
2350 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2356 pNew
->mNext
= mRuleList
;
2361 CVfrRulesDB::GetRuleId (
2365 SVfrRuleNode
*pNode
;
2367 if (RuleName
== NULL
) {
2368 return EFI_RULE_ID_INVALID
;
2371 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2372 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2373 return pNode
->mRuleId
;
2377 return EFI_RULE_ID_INVALID
;
2380 CVfrRulesDB gCVfrRulesDB
;
2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2386 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2387 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2388 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2389 mVarType
= EFI_IFR_TYPE_OTHER
;
2393 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2394 IN EFI_VARSTORE_INFO
&Info
2397 mVarStoreId
= Info
.mVarStoreId
;
2398 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2399 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2400 mVarType
= Info
.mVarType
;
2401 mVarTotalSize
= Info
.mVarTotalSize
;
2405 EFI_VARSTORE_INFO::operator= (
2406 IN CONST EFI_VARSTORE_INFO
&Info
2409 if (this != &Info
) {
2410 mVarStoreId
= Info
.mVarStoreId
;
2411 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2412 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2413 mVarType
= Info
.mVarType
;
2414 mVarTotalSize
= Info
.mVarTotalSize
;
2421 EFI_VARSTORE_INFO::operator == (
2422 IN EFI_VARSTORE_INFO
*Info
2425 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2426 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2427 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2428 (mVarType
== Info
->mVarType
) &&
2429 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2436 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2437 IN EFI_VARSTORE_INFO
*Info
2440 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2441 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2442 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2443 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2447 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2449 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2450 mVarStoreInfo
.mVarTotalSize
= 0;
2451 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2452 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2456 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2459 CVfrQuestionDB::GetFreeQuestionId (
2463 UINT32 Index
, Mask
, Offset
;
2465 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2466 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2471 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2472 return EFI_QUESTION_ID_INVALID
;
2475 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2476 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2477 mFreeQIdBitMap
[Index
] |= Mask
;
2478 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2482 return EFI_QUESTION_ID_INVALID
;
2486 CVfrQuestionDB::ChekQuestionIdFree (
2487 IN EFI_QUESTION_ID QId
2490 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2491 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2493 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2497 CVfrQuestionDB::MarkQuestionIdUsed (
2498 IN EFI_QUESTION_ID QId
2501 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2502 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2504 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2508 CVfrQuestionDB::MarkQuestionIdUnused (
2509 IN EFI_QUESTION_ID QId
2512 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2513 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2515 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2518 SVfrQuestionNode::SVfrQuestionNode (
2526 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2529 mQtype
= QUESTION_NORMAL
;
2532 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2533 strcpy (mName
, "$DEFAULT");
2535 mName
= new CHAR8
[strlen (Name
) + 1];
2536 strcpy (mName
, Name
);
2539 if (VarIdStr
!= NULL
) {
2540 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2541 strcpy (mVarIdStr
, VarIdStr
);
2543 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2544 strcpy (mVarIdStr
, "$");
2548 SVfrQuestionNode::~SVfrQuestionNode (
2552 if (mName
!= NULL
) {
2556 if (mVarIdStr
!= NULL
) {
2561 CVfrQuestionDB::CVfrQuestionDB ()
2565 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2566 mFreeQIdBitMap
[Index
] = 0;
2569 // Question ID 0 is reserved.
2570 mFreeQIdBitMap
[0] = 0x80000000;
2571 mQuestionList
= NULL
;
2574 CVfrQuestionDB::~CVfrQuestionDB ()
2576 SVfrQuestionNode
*pNode
;
2578 while (mQuestionList
!= NULL
) {
2579 pNode
= mQuestionList
;
2580 mQuestionList
= mQuestionList
->mNext
;
2586 // Reset to init state
2589 CVfrQuestionDB::ResetInit(
2594 SVfrQuestionNode
*pNode
;
2596 while (mQuestionList
!= NULL
) {
2597 pNode
= mQuestionList
;
2598 mQuestionList
= mQuestionList
->mNext
;
2602 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2603 mFreeQIdBitMap
[Index
] = 0;
2606 // Question ID 0 is reserved.
2607 mFreeQIdBitMap
[0] = 0x80000000;
2608 mQuestionList
= NULL
;
2612 CVfrQuestionDB::PrintAllQuestion (
2616 SVfrQuestionNode
*pNode
= NULL
;
2618 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2619 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2624 CVfrQuestionDB::RegisterQuestion (
2627 IN OUT EFI_QUESTION_ID
&QuestionId
2630 SVfrQuestionNode
*pNode
= NULL
;
2632 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2633 return VFR_RETURN_REDEFINED
;
2636 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2637 return VFR_RETURN_OUT_FOR_RESOURCES
;
2640 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2641 QuestionId
= GetFreeQuestionId ();
2644 // For Framework Vfr, don't check question ID conflict.
2646 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2648 return VFR_RETURN_QUESTIONID_REDEFINED
;
2650 MarkQuestionIdUsed (QuestionId
);
2652 pNode
->mQuestionId
= QuestionId
;
2654 pNode
->mNext
= mQuestionList
;
2655 mQuestionList
= pNode
;
2657 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2659 return VFR_RETURN_SUCCESS
;
2663 CVfrQuestionDB::RegisterOldDateQuestion (
2664 IN CHAR8
*YearVarId
,
2665 IN CHAR8
*MonthVarId
,
2667 IN OUT EFI_QUESTION_ID
&QuestionId
2670 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2673 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2677 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2680 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2683 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2687 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2688 QuestionId
= GetFreeQuestionId ();
2690 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2693 MarkQuestionIdUsed (QuestionId
);
2696 pNode
[0]->mQuestionId
= QuestionId
;
2697 pNode
[1]->mQuestionId
= QuestionId
;
2698 pNode
[2]->mQuestionId
= QuestionId
;
2699 pNode
[0]->mQtype
= QUESTION_DATE
;
2700 pNode
[1]->mQtype
= QUESTION_DATE
;
2701 pNode
[2]->mQtype
= QUESTION_DATE
;
2702 pNode
[0]->mNext
= pNode
[1];
2703 pNode
[1]->mNext
= pNode
[2];
2704 pNode
[2]->mNext
= mQuestionList
;
2705 mQuestionList
= pNode
[0];
2707 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2708 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2709 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2714 for (Index
= 0; Index
< 3; Index
++) {
2715 if (pNode
[Index
] != NULL
) {
2716 delete pNode
[Index
];
2719 QuestionId
= EFI_QUESTION_ID_INVALID
;
2723 CVfrQuestionDB::RegisterNewDateQuestion (
2725 IN CHAR8
*BaseVarId
,
2726 IN OUT EFI_QUESTION_ID
&QuestionId
2729 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2731 CHAR8
*VarIdStr
[3] = {NULL
, };
2734 if (BaseVarId
== NULL
&& Name
== NULL
) {
2735 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2736 QuestionId
= GetFreeQuestionId ();
2738 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2741 MarkQuestionIdUsed (QuestionId
);
2746 if (BaseVarId
!= NULL
) {
2747 Len
= strlen (BaseVarId
);
2749 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2750 if (VarIdStr
[0] != NULL
) {
2751 strcpy (VarIdStr
[0], BaseVarId
);
2752 strcat (VarIdStr
[0], ".Year");
2754 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2755 if (VarIdStr
[1] != NULL
) {
2756 strcpy (VarIdStr
[1], BaseVarId
);
2757 strcat (VarIdStr
[1], ".Month");
2759 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2760 if (VarIdStr
[2] != NULL
) {
2761 strcpy (VarIdStr
[2], BaseVarId
);
2762 strcat (VarIdStr
[2], ".Day");
2765 Len
= strlen (Name
);
2767 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2768 if (VarIdStr
[0] != NULL
) {
2769 strcpy (VarIdStr
[0], Name
);
2770 strcat (VarIdStr
[0], ".Year");
2772 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2773 if (VarIdStr
[1] != NULL
) {
2774 strcpy (VarIdStr
[1], Name
);
2775 strcat (VarIdStr
[1], ".Month");
2777 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2778 if (VarIdStr
[2] != NULL
) {
2779 strcpy (VarIdStr
[2], Name
);
2780 strcat (VarIdStr
[2], ".Day");
2784 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2787 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2790 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2794 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2795 QuestionId
= GetFreeQuestionId ();
2797 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2800 MarkQuestionIdUsed (QuestionId
);
2803 pNode
[0]->mQuestionId
= QuestionId
;
2804 pNode
[1]->mQuestionId
= QuestionId
;
2805 pNode
[2]->mQuestionId
= QuestionId
;
2806 pNode
[0]->mQtype
= QUESTION_DATE
;
2807 pNode
[1]->mQtype
= QUESTION_DATE
;
2808 pNode
[2]->mQtype
= QUESTION_DATE
;
2809 pNode
[0]->mNext
= pNode
[1];
2810 pNode
[1]->mNext
= pNode
[2];
2811 pNode
[2]->mNext
= mQuestionList
;
2812 mQuestionList
= pNode
[0];
2814 for (Index
= 0; Index
< 3; Index
++) {
2815 if (VarIdStr
[Index
] != NULL
) {
2816 delete VarIdStr
[Index
];
2820 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2821 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2822 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2827 for (Index
= 0; Index
< 3; Index
++) {
2828 if (pNode
[Index
] != NULL
) {
2829 delete pNode
[Index
];
2832 if (VarIdStr
[Index
] != NULL
) {
2833 delete VarIdStr
[Index
];
2839 CVfrQuestionDB::RegisterOldTimeQuestion (
2840 IN CHAR8
*HourVarId
,
2841 IN CHAR8
*MinuteVarId
,
2842 IN CHAR8
*SecondVarId
,
2843 IN OUT EFI_QUESTION_ID
&QuestionId
2846 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2849 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2853 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2856 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2859 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2863 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2864 QuestionId
= GetFreeQuestionId ();
2866 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2869 MarkQuestionIdUsed (QuestionId
);
2872 pNode
[0]->mQuestionId
= QuestionId
;
2873 pNode
[1]->mQuestionId
= QuestionId
;
2874 pNode
[2]->mQuestionId
= QuestionId
;
2875 pNode
[0]->mQtype
= QUESTION_TIME
;
2876 pNode
[1]->mQtype
= QUESTION_TIME
;
2877 pNode
[2]->mQtype
= QUESTION_TIME
;
2878 pNode
[0]->mNext
= pNode
[1];
2879 pNode
[1]->mNext
= pNode
[2];
2880 pNode
[2]->mNext
= mQuestionList
;
2881 mQuestionList
= pNode
[0];
2883 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2884 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2885 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2890 for (Index
= 0; Index
< 3; Index
++) {
2891 if (pNode
[Index
] != NULL
) {
2892 delete pNode
[Index
];
2895 QuestionId
= EFI_QUESTION_ID_INVALID
;
2899 CVfrQuestionDB::RegisterNewTimeQuestion (
2901 IN CHAR8
*BaseVarId
,
2902 IN OUT EFI_QUESTION_ID
&QuestionId
2905 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2907 CHAR8
*VarIdStr
[3] = {NULL
, };
2910 if (BaseVarId
== NULL
&& Name
== NULL
) {
2911 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2912 QuestionId
= GetFreeQuestionId ();
2914 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2917 MarkQuestionIdUsed (QuestionId
);
2922 if (BaseVarId
!= NULL
) {
2923 Len
= strlen (BaseVarId
);
2925 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2926 if (VarIdStr
[0] != NULL
) {
2927 strcpy (VarIdStr
[0], BaseVarId
);
2928 strcat (VarIdStr
[0], ".Hour");
2930 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2931 if (VarIdStr
[1] != NULL
) {
2932 strcpy (VarIdStr
[1], BaseVarId
);
2933 strcat (VarIdStr
[1], ".Minute");
2935 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2936 if (VarIdStr
[2] != NULL
) {
2937 strcpy (VarIdStr
[2], BaseVarId
);
2938 strcat (VarIdStr
[2], ".Second");
2941 Len
= strlen (Name
);
2943 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2944 if (VarIdStr
[0] != NULL
) {
2945 strcpy (VarIdStr
[0], Name
);
2946 strcat (VarIdStr
[0], ".Hour");
2948 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2949 if (VarIdStr
[1] != NULL
) {
2950 strcpy (VarIdStr
[1], Name
);
2951 strcat (VarIdStr
[1], ".Minute");
2953 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2954 if (VarIdStr
[2] != NULL
) {
2955 strcpy (VarIdStr
[2], Name
);
2956 strcat (VarIdStr
[2], ".Second");
2960 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2963 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2966 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2970 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2971 QuestionId
= GetFreeQuestionId ();
2973 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2976 MarkQuestionIdUsed (QuestionId
);
2979 pNode
[0]->mQuestionId
= QuestionId
;
2980 pNode
[1]->mQuestionId
= QuestionId
;
2981 pNode
[2]->mQuestionId
= QuestionId
;
2982 pNode
[0]->mQtype
= QUESTION_TIME
;
2983 pNode
[1]->mQtype
= QUESTION_TIME
;
2984 pNode
[2]->mQtype
= QUESTION_TIME
;
2985 pNode
[0]->mNext
= pNode
[1];
2986 pNode
[1]->mNext
= pNode
[2];
2987 pNode
[2]->mNext
= mQuestionList
;
2988 mQuestionList
= pNode
[0];
2990 for (Index
= 0; Index
< 3; Index
++) {
2991 if (VarIdStr
[Index
] != NULL
) {
2992 delete VarIdStr
[Index
];
2996 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2997 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2998 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3003 for (Index
= 0; Index
< 3; Index
++) {
3004 if (pNode
[Index
] != NULL
) {
3005 delete pNode
[Index
];
3008 if (VarIdStr
[Index
] != NULL
) {
3009 delete VarIdStr
[Index
];
3015 CVfrQuestionDB::RegisterRefQuestion (
3017 IN CHAR8
*BaseVarId
,
3018 IN OUT EFI_QUESTION_ID
&QuestionId
3021 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3023 CHAR8
*VarIdStr
[4] = {NULL
, };
3026 if (BaseVarId
== NULL
&& Name
== NULL
) {
3030 if (BaseVarId
!= NULL
) {
3031 Len
= strlen (BaseVarId
);
3033 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3034 if (VarIdStr
[0] != NULL
) {
3035 strcpy (VarIdStr
[0], BaseVarId
);
3036 strcat (VarIdStr
[0], ".QuestionId");
3038 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3039 if (VarIdStr
[1] != NULL
) {
3040 strcpy (VarIdStr
[1], BaseVarId
);
3041 strcat (VarIdStr
[1], ".FormId");
3043 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3044 if (VarIdStr
[2] != NULL
) {
3045 strcpy (VarIdStr
[2], BaseVarId
);
3046 strcat (VarIdStr
[2], ".FormSetGuid");
3048 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3049 if (VarIdStr
[3] != NULL
) {
3050 strcpy (VarIdStr
[3], BaseVarId
);
3051 strcat (VarIdStr
[3], ".DevicePath");
3054 Len
= strlen (Name
);
3056 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3057 if (VarIdStr
[0] != NULL
) {
3058 strcpy (VarIdStr
[0], Name
);
3059 strcat (VarIdStr
[0], ".QuestionId");
3061 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3062 if (VarIdStr
[1] != NULL
) {
3063 strcpy (VarIdStr
[1], Name
);
3064 strcat (VarIdStr
[1], ".FormId");
3066 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3067 if (VarIdStr
[2] != NULL
) {
3068 strcpy (VarIdStr
[2], Name
);
3069 strcat (VarIdStr
[2], ".FormSetGuid");
3071 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3072 if (VarIdStr
[3] != NULL
) {
3073 strcpy (VarIdStr
[3], Name
);
3074 strcat (VarIdStr
[3], ".DevicePath");
3078 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3081 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3084 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3087 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3091 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3092 QuestionId
= GetFreeQuestionId ();
3094 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3097 MarkQuestionIdUsed (QuestionId
);
3100 pNode
[0]->mQuestionId
= QuestionId
;
3101 pNode
[1]->mQuestionId
= QuestionId
;
3102 pNode
[2]->mQuestionId
= QuestionId
;
3103 pNode
[3]->mQuestionId
= QuestionId
;
3104 pNode
[0]->mQtype
= QUESTION_REF
;
3105 pNode
[1]->mQtype
= QUESTION_REF
;
3106 pNode
[2]->mQtype
= QUESTION_REF
;
3107 pNode
[3]->mQtype
= QUESTION_REF
;
3108 pNode
[0]->mNext
= pNode
[1];
3109 pNode
[1]->mNext
= pNode
[2];
3110 pNode
[2]->mNext
= pNode
[3];
3111 pNode
[3]->mNext
= mQuestionList
;
3112 mQuestionList
= pNode
[0];
3114 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3115 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3116 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3117 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3122 for (Index
= 0; Index
< 4; Index
++) {
3123 if (pNode
[Index
] != NULL
) {
3124 delete pNode
[Index
];
3127 if (VarIdStr
[Index
] != NULL
) {
3128 delete VarIdStr
[Index
];
3134 CVfrQuestionDB::UpdateQuestionId (
3135 IN EFI_QUESTION_ID QId
,
3136 IN EFI_QUESTION_ID NewQId
3139 SVfrQuestionNode
*pNode
= NULL
;
3141 if (QId
== NewQId
) {
3143 return VFR_RETURN_SUCCESS
;
3147 // For Framework Vfr, don't check question ID conflict.
3149 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3150 return VFR_RETURN_REDEFINED
;
3153 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3154 if (pNode
->mQuestionId
== QId
) {
3159 if (pNode
== NULL
) {
3160 return VFR_RETURN_UNDEFINED
;
3163 MarkQuestionIdUnused (QId
);
3164 pNode
->mQuestionId
= NewQId
;
3165 MarkQuestionIdUsed (NewQId
);
3167 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3169 return VFR_RETURN_SUCCESS
;
3173 CVfrQuestionDB::GetQuestionId (
3176 OUT EFI_QUESTION_ID
&QuestionId
,
3177 OUT UINT32
&BitMask
,
3178 OUT EFI_QUESION_TYPE
*QType
3181 SVfrQuestionNode
*pNode
;
3183 QuestionId
= EFI_QUESTION_ID_INVALID
;
3184 BitMask
= 0x00000000;
3185 if (QType
!= NULL
) {
3186 *QType
= QUESTION_NORMAL
;
3189 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3193 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3195 if (strcmp (pNode
->mName
, Name
) != 0) {
3200 if (VarIdStr
!= NULL
) {
3201 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3206 QuestionId
= pNode
->mQuestionId
;
3207 BitMask
= pNode
->mBitMask
;
3208 if (QType
!= NULL
) {
3209 *QType
= pNode
->mQtype
;
3218 CVfrQuestionDB::FindQuestion (
3219 IN EFI_QUESTION_ID QuestionId
3222 SVfrQuestionNode
*pNode
;
3224 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3225 return VFR_RETURN_INVALID_PARAMETER
;
3228 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3229 if (pNode
->mQuestionId
== QuestionId
) {
3230 return VFR_RETURN_SUCCESS
;
3234 return VFR_RETURN_UNDEFINED
;
3238 CVfrQuestionDB::FindQuestion (
3242 SVfrQuestionNode
*pNode
;
3245 return VFR_RETURN_FATAL_ERROR
;
3248 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3249 if (strcmp (pNode
->mName
, Name
) == 0) {
3250 return VFR_RETURN_SUCCESS
;
3254 return VFR_RETURN_UNDEFINED
;
3257 CVfrStringDB::CVfrStringDB ()
3259 mStringFileName
= NULL
;
3262 CVfrStringDB::~CVfrStringDB ()
3264 if (mStringFileName
!= NULL
) {
3265 delete mStringFileName
;
3267 mStringFileName
= NULL
;
3272 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3276 if (StringFileName
== NULL
) {
3280 FileLen
= strlen (StringFileName
) + 1;
3281 mStringFileName
= new CHAR8
[FileLen
];
3282 if (mStringFileName
== NULL
) {
3286 strcpy (mStringFileName
, StringFileName
);
3287 mStringFileName
[FileLen
- 1] = '\0';
3292 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3293 from a set of supported languages.
3295 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3296 contains a set of language codes.
3297 @param[in] Language A variable that contains pointers to Null-terminated
3298 ASCII strings that contain one language codes.
3300 @retval FALSE The best matching language could not be found in SupportedLanguages.
3301 @retval TRUE The best matching language could be found in SupportedLanguages.
3305 CVfrStringDB::GetBestLanguage (
3306 IN CONST CHAR8
*SupportedLanguages
,
3310 UINTN CompareLength
;
3311 UINTN LanguageLength
;
3312 CONST CHAR8
*Supported
;
3314 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3319 // Determine the length of the first RFC 4646 language code in Language
3321 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3324 // Trim back the length of Language used until it is empty
3326 while (LanguageLength
> 0) {
3328 // Loop through all language codes in SupportedLanguages
3330 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3332 // Skip ';' characters in Supported
3334 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3336 // Determine the length of the next language code in Supported
3338 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3340 // If Language is longer than the Supported, then skip to the next language
3342 if (LanguageLength
> CompareLength
) {
3347 // See if the first LanguageLength characters in Supported match Language
3349 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3355 // Trim Language from the right to the next '-' character
3357 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3361 // No matches were found
3368 CVfrStringDB::GetVarStoreNameFormStringId (
3369 IN EFI_STRING_ID StringId
3372 FILE *pInFile
= NULL
;
3377 CHAR16
*UnicodeString
;
3378 CHAR8
*VarStoreName
= NULL
;
3382 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3384 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3386 if (mStringFileName
== NULL
) {
3390 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3397 fseek (pInFile
, 0, SEEK_END
);
3398 Length
= ftell (pInFile
);
3399 fseek (pInFile
, 0, SEEK_SET
);
3404 StringPtr
= new UINT8
[Length
];
3405 if (StringPtr
== NULL
) {
3409 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3412 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3414 // Check the String package.
3416 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3422 // Search the language, get best language base on RFC 4647 matching algorithm.
3424 Current
= StringPtr
;
3425 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3426 Current
+= PkgHeader
->Header
.Length
;
3427 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3429 // If can't find string package base on language, just return the first string package.
3431 if (Current
- StringPtr
>= Length
) {
3432 Current
= StringPtr
;
3433 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3438 Current
+= PkgHeader
->HdrSize
;
3440 // Find the string block according the stringId.
3442 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3443 if (Status
!= EFI_SUCCESS
) {
3449 // Get varstore name according the string type.
3451 switch (BlockType
) {
3452 case EFI_HII_SIBT_STRING_SCSU
:
3453 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3454 case EFI_HII_SIBT_STRINGS_SCSU
:
3455 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3456 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3457 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3458 strcpy (VarStoreName
, StringName
);
3460 case EFI_HII_SIBT_STRING_UCS2
:
3461 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3462 case EFI_HII_SIBT_STRINGS_UCS2
:
3463 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3464 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3465 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3466 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3467 VarStoreName
= DestTmp
;
3468 while (*UnicodeString
!= '\0') {
3469 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3479 return VarStoreName
;
3483 CVfrStringDB::FindStringBlock (
3484 IN UINT8
*StringData
,
3485 IN EFI_STRING_ID StringId
,
3486 OUT UINT32
*StringTextOffset
,
3487 OUT UINT8
*BlockType
3491 EFI_STRING_ID CurrentStringId
;
3494 UINT8
*StringTextPtr
;
3499 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3503 CurrentStringId
= 1;
3506 // Parse the string blocks to get the string text and font.
3508 BlockHdr
= StringData
;
3511 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3512 switch (*BlockHdr
) {
3513 case EFI_HII_SIBT_STRING_SCSU
:
3514 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3515 StringTextPtr
= BlockHdr
+ Offset
;
3516 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3520 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3521 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3522 StringTextPtr
= BlockHdr
+ Offset
;
3523 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3527 case EFI_HII_SIBT_STRINGS_SCSU
:
3528 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3529 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3530 BlockSize
+= StringTextPtr
- BlockHdr
;
3532 for (Index
= 0; Index
< StringCount
; Index
++) {
3533 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3534 if (CurrentStringId
== StringId
) {
3535 *BlockType
= *BlockHdr
;
3536 *StringTextOffset
= StringTextPtr
- StringData
;
3539 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3544 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3547 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3550 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3551 BlockSize
+= StringTextPtr
- BlockHdr
;
3553 for (Index
= 0; Index
< StringCount
; Index
++) {
3554 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3555 if (CurrentStringId
== StringId
) {
3556 *BlockType
= *BlockHdr
;
3557 *StringTextOffset
= StringTextPtr
- StringData
;
3560 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3565 case EFI_HII_SIBT_STRING_UCS2
:
3566 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3567 StringTextPtr
= BlockHdr
+ Offset
;
3569 // Use StringSize to store the size of the specified string, including the NULL
3572 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3573 BlockSize
+= Offset
+ StringSize
;
3577 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3578 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3579 StringTextPtr
= BlockHdr
+ Offset
;
3581 // Use StrSize to store the size of the specified string, including the NULL
3584 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3585 BlockSize
+= Offset
+ StringSize
;
3589 case EFI_HII_SIBT_STRINGS_UCS2
:
3590 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3591 StringTextPtr
= BlockHdr
+ Offset
;
3592 BlockSize
+= Offset
;
3593 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3594 for (Index
= 0; Index
< StringCount
; Index
++) {
3595 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3596 BlockSize
+= StringSize
;
3597 if (CurrentStringId
== StringId
) {
3598 *BlockType
= *BlockHdr
;
3599 *StringTextOffset
= StringTextPtr
- StringData
;
3602 StringTextPtr
= StringTextPtr
+ StringSize
;
3607 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3608 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3609 StringTextPtr
= BlockHdr
+ Offset
;
3610 BlockSize
+= Offset
;
3613 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3616 for (Index
= 0; Index
< StringCount
; Index
++) {
3617 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3618 BlockSize
+= StringSize
;
3619 if (CurrentStringId
== StringId
) {
3620 *BlockType
= *BlockHdr
;
3621 *StringTextOffset
= StringTextPtr
- StringData
;
3624 StringTextPtr
= StringTextPtr
+ StringSize
;
3629 case EFI_HII_SIBT_DUPLICATE
:
3630 if (CurrentStringId
== StringId
) {
3632 // Incoming StringId is an id of a duplicate string block.
3633 // Update the StringId to be the previous string block.
3634 // Go back to the header of string block to search.
3638 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3639 sizeof (EFI_STRING_ID
)
3641 CurrentStringId
= 1;
3644 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3649 case EFI_HII_SIBT_SKIP1
:
3650 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3651 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3652 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3655 case EFI_HII_SIBT_SKIP2
:
3656 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3657 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3658 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3661 case EFI_HII_SIBT_EXT1
:
3664 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3667 BlockSize
+= Length8
;
3670 case EFI_HII_SIBT_EXT2
:
3671 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3672 BlockSize
+= Ext2
.Length
;
3675 case EFI_HII_SIBT_EXT4
:
3678 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3682 BlockSize
+= Length32
;
3689 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3690 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3691 *BlockType
= *BlockHdr
;
3693 if (StringId
== CurrentStringId
- 1) {
3695 // if only one skip item, return EFI_NOT_FOUND.
3697 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3698 return EFI_NOT_FOUND
;
3704 if (StringId
< CurrentStringId
- 1) {
3705 return EFI_NOT_FOUND
;
3708 BlockHdr
= StringData
+ BlockSize
;
3711 return EFI_NOT_FOUND
;
3715 CVfrStringDB::GetUnicodeStringTextSize (
3722 StringSize
= sizeof (CHAR16
);
3723 StringPtr
= (UINT16
*)StringSrc
;
3724 while (*StringPtr
++ != L
'\0') {
3725 StringSize
+= sizeof (CHAR16
);
3731 BOOLEAN VfrCompatibleMode
= FALSE
;
3733 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3734 CVfrDefaultStore gCVfrDefaultStore
;
3735 CVfrDataStorage gCVfrDataStorage
;