3 Vfr common library functions.
5 Copyright (c) 2004 - 2016, 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
,
1019 SVfrDataField
*pNewField
= NULL
;
1020 SVfrDataType
*pFieldType
= NULL
;
1021 SVfrDataField
*pTmp
;
1024 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1026 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1027 return VFR_RETURN_INVALID_PARAMETER
;
1030 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1031 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1032 return VFR_RETURN_REDEFINED
;
1036 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1038 if ((pNewField
= new SVfrDataField
) == NULL
) {
1039 return VFR_RETURN_OUT_FOR_RESOURCES
;
1041 strcpy (pNewField
->mFieldName
, FieldName
);
1042 pNewField
->mFieldType
= pFieldType
;
1043 pNewField
->mArrayNum
= ArrayNum
;
1044 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1045 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1047 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1049 if (mNewDataType
->mMembers
== NULL
) {
1050 mNewDataType
->mMembers
= pNewField
;
1051 pNewField
->mNext
= NULL
;
1053 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1055 pTmp
->mNext
= pNewField
;
1056 pNewField
->mNext
= NULL
;
1059 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1060 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1062 return VFR_RETURN_SUCCESS
;
1066 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1070 if (mNewDataType
->mTypeName
[0] == '\0') {
1074 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1075 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1078 RegisterNewType (mNewDataType
);
1079 if (mFirstNewDataTypeName
== NULL
) {
1080 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1083 mNewDataType
= NULL
;
1087 CVfrVarDataTypeDB::GetDataType (
1089 OUT SVfrDataType
**DataType
1092 SVfrDataType
*pDataType
= NULL
;
1094 if (TypeName
== NULL
) {
1095 return VFR_RETURN_ERROR_SKIPED
;
1098 if (DataType
== NULL
) {
1099 return VFR_RETURN_FATAL_ERROR
;
1104 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1105 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1106 *DataType
= pDataType
;
1107 return VFR_RETURN_SUCCESS
;
1111 return VFR_RETURN_UNDEFINED
;
1115 CVfrVarDataTypeDB::GetDataTypeSize (
1120 SVfrDataType
*pDataType
= NULL
;
1123 return VFR_RETURN_FATAL_ERROR
;
1127 DataType
= DataType
& 0x0F;
1130 // For user defined data type, the size can't be got by this function.
1132 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1133 return VFR_RETURN_SUCCESS
;
1136 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1137 if (DataType
== pDataType
->mType
) {
1138 *Size
= pDataType
->mTotalSize
;
1139 return VFR_RETURN_SUCCESS
;
1143 return VFR_RETURN_UNDEFINED
;
1147 CVfrVarDataTypeDB::GetDataTypeSize (
1152 SVfrDataType
*pDataType
= NULL
;
1155 return VFR_RETURN_FATAL_ERROR
;
1160 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1161 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1162 *Size
= pDataType
->mTotalSize
;
1163 return VFR_RETURN_SUCCESS
;
1167 return VFR_RETURN_UNDEFINED
;
1171 CVfrVarDataTypeDB::GetDataFieldInfo (
1178 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1179 UINT32 ArrayIdx
, Tmp
;
1180 SVfrDataType
*pType
= NULL
;
1181 SVfrDataField
*pField
= NULL
;
1184 Type
= EFI_IFR_TYPE_OTHER
;
1187 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1188 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1191 // if it is not struct data type
1193 Type
= pType
->mType
;
1194 Size
= pType
->mTotalSize
;
1196 while (*VarStr
!= '\0') {
1197 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1198 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1199 pType
= pField
->mFieldType
;
1200 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1201 Offset
= (UINT16
) (Offset
+ Tmp
);
1202 Type
= GetFieldWidth (pField
);
1203 Size
= GetFieldSize (pField
, ArrayIdx
);
1205 return VFR_RETURN_SUCCESS
;
1209 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1210 OUT CHAR8
***NameList
,
1211 OUT UINT32
*ListSize
1215 SVfrDataType
*pType
;
1217 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1218 return VFR_RETURN_FATAL_ERROR
;
1224 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1225 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1230 if (*ListSize
== 0) {
1231 return VFR_RETURN_SUCCESS
;
1234 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1236 return VFR_RETURN_OUT_FOR_RESOURCES
;
1239 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1240 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1241 (*NameList
)[Index
] = pType
->mTypeName
;
1244 return VFR_RETURN_SUCCESS
;
1248 CVfrVarDataTypeDB::IsTypeNameDefined (
1252 SVfrDataType
*pType
;
1254 if (TypeName
== NULL
) {
1258 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1259 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1268 CVfrVarDataTypeDB::Dump (
1272 SVfrDataType
*pTNode
;
1273 SVfrDataField
*pFNode
;
1275 fprintf (File
, "\n\n***************************************************************\n");
1276 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1277 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1278 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1279 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1280 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1281 if (pFNode
->mArrayNum
> 0) {
1282 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1283 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1285 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1286 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1289 fprintf (File
, "\t\t};\n");
1290 fprintf (File
, "---------------------------------------------------------------\n");
1292 fprintf (File
, "***************************************************************\n");
1295 #ifdef CVFR_VARDATATYPEDB_DEBUG
1297 CVfrVarDataTypeDB::ParserDB (
1301 SVfrDataType
*pTNode
;
1302 SVfrDataField
*pFNode
;
1304 printf ("***************************************************************\n");
1305 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1306 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1307 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1308 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1309 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1310 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1312 printf ("\t\t};\n");
1313 printf ("---------------------------------------------------------------\n");
1315 printf ("***************************************************************\n");
1319 SVfrVarStorageNode::SVfrVarStorageNode (
1321 IN CHAR8
*StoreName
,
1322 IN EFI_VARSTORE_ID VarStoreId
,
1323 IN EFI_STRING_ID VarName
,
1331 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1333 if (StoreName
!= NULL
) {
1334 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1335 strcpy (mVarStoreName
, StoreName
);
1337 mVarStoreName
= NULL
;
1340 mVarStoreId
= VarStoreId
;
1341 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1342 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1343 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1344 mAssignedFlag
= Flag
;
1347 SVfrVarStorageNode::SVfrVarStorageNode (
1349 IN CHAR8
*StoreName
,
1350 IN EFI_VARSTORE_ID VarStoreId
,
1351 IN SVfrDataType
*DataType
,
1358 memset (&mGuid
, 0, sizeof (EFI_GUID
));
1360 if (StoreName
!= NULL
) {
1361 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1362 strcpy (mVarStoreName
, StoreName
);
1364 mVarStoreName
= NULL
;
1367 mVarStoreId
= VarStoreId
;
1368 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1369 mStorageInfo
.mDataType
= DataType
;
1370 mAssignedFlag
= Flag
;
1373 SVfrVarStorageNode::SVfrVarStorageNode (
1374 IN CHAR8
*StoreName
,
1375 IN EFI_VARSTORE_ID VarStoreId
1378 if (StoreName
!= NULL
) {
1379 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1380 strcpy (mVarStoreName
, StoreName
);
1382 mVarStoreName
= NULL
;
1385 mVarStoreId
= VarStoreId
;
1386 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1387 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1388 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1391 SVfrVarStorageNode::~SVfrVarStorageNode (
1395 if (mVarStoreName
!= NULL
) {
1396 delete[] mVarStoreName
;
1399 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1400 delete mStorageInfo
.mNameSpace
.mNameTable
;
1404 CVfrDataStorage::CVfrDataStorage (
1410 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1411 mFreeVarStoreIdBitMap
[Index
] = 0;
1414 // Question ID 0 is reserved.
1415 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1417 mBufferVarStoreList
= NULL
;
1418 mEfiVarStoreList
= NULL
;
1419 mNameVarStoreList
= NULL
;
1420 mCurrVarStorageNode
= NULL
;
1421 mNewVarStorageNode
= NULL
;
1422 mBufferFieldInfoListHead
= NULL
;
1423 mBufferFieldInfoListTail
= NULL
;
1426 CVfrDataStorage::~CVfrDataStorage (
1430 SVfrVarStorageNode
*pNode
;
1432 while (mBufferVarStoreList
!= NULL
) {
1433 pNode
= mBufferVarStoreList
;
1434 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1437 while (mEfiVarStoreList
!= NULL
) {
1438 pNode
= mEfiVarStoreList
;
1439 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1442 while (mNameVarStoreList
!= NULL
) {
1443 pNode
= mNameVarStoreList
;
1444 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1447 if (mNewVarStorageNode
!= NULL
) {
1448 delete mNewVarStorageNode
;
1453 CVfrDataStorage::GetFreeVarStoreId (
1454 EFI_VFR_VARSTORE_TYPE VarType
1457 UINT32 Index
, Mask
, Offset
;
1460 // Assign the different ID range for the different type VarStore to support Framework Vfr
1463 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1465 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1467 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1471 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1472 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1477 if (Index
== EFI_FREE_VARSTORE_ID_BITMAP_SIZE
) {
1478 return EFI_VARSTORE_ID_INVALID
;
1481 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1482 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1483 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1484 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1488 return EFI_VARSTORE_ID_INVALID
;
1492 CVfrDataStorage::ChekVarStoreIdFree (
1493 IN EFI_VARSTORE_ID VarStoreId
1496 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1497 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1499 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1503 CVfrDataStorage::MarkVarStoreIdUsed (
1504 IN EFI_VARSTORE_ID VarStoreId
1507 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1508 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1510 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1514 CVfrDataStorage::MarkVarStoreIdUnused (
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::DeclareNameVarStoreBegin (
1526 IN CHAR8
*StoreName
,
1527 IN EFI_VARSTORE_ID VarStoreId
1530 SVfrVarStorageNode
*pNode
= NULL
;
1531 EFI_VARSTORE_ID TmpVarStoreId
;
1533 if (StoreName
== NULL
) {
1534 return VFR_RETURN_FATAL_ERROR
;
1537 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1538 return VFR_RETURN_REDEFINED
;
1541 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1542 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1544 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1545 return VFR_RETURN_VARSTOREID_REDEFINED
;
1547 MarkVarStoreIdUsed (VarStoreId
);
1550 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1551 return VFR_RETURN_UNDEFINED
;
1554 mNewVarStorageNode
= pNode
;
1556 return VFR_RETURN_SUCCESS
;
1560 CVfrDataStorage::NameTableAddItem (
1561 IN EFI_STRING_ID Item
1564 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1567 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1568 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1570 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1571 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1572 return VFR_RETURN_OUT_FOR_RESOURCES
;
1574 memcpy (NewTable
, OldTable
, TableSize
);
1575 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1578 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1579 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1581 return VFR_RETURN_SUCCESS
;
1585 CVfrDataStorage::DeclareNameVarStoreEnd (
1589 mNewVarStorageNode
->mGuid
= *Guid
;
1590 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1591 mNameVarStoreList
= mNewVarStorageNode
;
1593 mNewVarStorageNode
= NULL
;
1595 return VFR_RETURN_SUCCESS
;
1599 CVfrDataStorage::DeclareEfiVarStore (
1600 IN CHAR8
*StoreName
,
1602 IN EFI_STRING_ID NameStrId
,
1607 SVfrVarStorageNode
*pNode
;
1608 EFI_VARSTORE_ID VarStoreId
;
1610 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1611 return VFR_RETURN_FATAL_ERROR
;
1614 if (VarSize
> sizeof (UINT64
)) {
1615 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1618 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1619 return VFR_RETURN_REDEFINED
;
1622 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1623 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1624 return VFR_RETURN_OUT_FOR_RESOURCES
;
1627 pNode
->mNext
= mEfiVarStoreList
;
1628 mEfiVarStoreList
= pNode
;
1630 return VFR_RETURN_SUCCESS
;
1634 CVfrDataStorage::DeclareBufferVarStore (
1635 IN CHAR8
*StoreName
,
1637 IN CVfrVarDataTypeDB
*DataTypeDB
,
1639 IN EFI_VARSTORE_ID VarStoreId
,
1643 SVfrVarStorageNode
*pNew
= NULL
;
1644 SVfrDataType
*pDataType
= NULL
;
1645 EFI_VARSTORE_ID TempVarStoreId
;
1647 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1648 return VFR_RETURN_FATAL_ERROR
;
1651 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1652 return VFR_RETURN_REDEFINED
;
1655 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1657 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1658 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1660 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1661 return VFR_RETURN_VARSTOREID_REDEFINED
;
1663 MarkVarStoreIdUsed (VarStoreId
);
1666 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1667 return VFR_RETURN_OUT_FOR_RESOURCES
;
1670 pNew
->mNext
= mBufferVarStoreList
;
1671 mBufferVarStoreList
= pNew
;
1673 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1674 return VFR_RETURN_FATAL_ERROR
;
1677 return VFR_RETURN_SUCCESS
;
1681 CVfrDataStorage::GetVarStoreByDataType (
1682 IN CHAR8
*DataTypeName
,
1683 OUT SVfrVarStorageNode
**VarNode
,
1684 IN EFI_GUID
*VarGuid
1687 SVfrVarStorageNode
*pNode
;
1688 SVfrVarStorageNode
*MatchNode
;
1691 // Framework VFR uses Data type name as varstore name, so don't need check again.
1693 if (VfrCompatibleMode
) {
1694 return VFR_RETURN_UNDEFINED
;
1698 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1699 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1703 if ((VarGuid
!= NULL
)) {
1704 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1706 return VFR_RETURN_SUCCESS
;
1709 if (MatchNode
== NULL
) {
1713 // More than one varstores referred the same data structures.
1715 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1720 if (MatchNode
== NULL
) {
1721 return VFR_RETURN_UNDEFINED
;
1724 *VarNode
= MatchNode
;
1725 return VFR_RETURN_SUCCESS
;
1729 CVfrDataStorage::CheckGuidField (
1730 IN SVfrVarStorageNode
*pNode
,
1731 IN EFI_GUID
*StoreGuid
,
1732 IN BOOLEAN
*HasFoundOne
,
1733 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1736 if (StoreGuid
!= NULL
) {
1738 // If has guid info, compare the guid filed.
1740 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1742 // Both name and guid are same, this this varstore.
1744 mCurrVarStorageNode
= pNode
;
1745 *ReturnCode
= VFR_RETURN_SUCCESS
;
1750 // Not has Guid field, check whether this name is the only one.
1754 // The name has conflict, return name redefined.
1756 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1760 *HasFoundOne
= TRUE
;
1761 mCurrVarStorageNode
= pNode
;
1768 Base on the input store name and guid to find the varstore id.
1770 If both name and guid are inputed, base on the name and guid to
1771 found the varstore. If only name inputed, base on the name to
1772 found the varstore and go on to check whether more than one varstore
1773 has the same name. If only has found one varstore, return this
1774 varstore; if more than one varstore has same name, return varstore
1775 name redefined error. If no varstore found by varstore name, call
1776 function GetVarStoreByDataType and use inputed varstore name as
1777 data type name to search.
1780 CVfrDataStorage::GetVarStoreId (
1781 IN CHAR8
*StoreName
,
1782 OUT EFI_VARSTORE_ID
*VarStoreId
,
1783 IN EFI_GUID
*StoreGuid
1786 EFI_VFR_RETURN_CODE ReturnCode
;
1787 SVfrVarStorageNode
*pNode
;
1788 BOOLEAN HasFoundOne
= FALSE
;
1790 mCurrVarStorageNode
= NULL
;
1792 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1793 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1794 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1795 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1801 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1802 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1803 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1804 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1810 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1811 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1812 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1813 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1820 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1821 return VFR_RETURN_SUCCESS
;
1824 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1827 // Assume that Data strucutre name is used as StoreName, and check again.
1829 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1830 if (pNode
!= NULL
) {
1831 mCurrVarStorageNode
= pNode
;
1832 *VarStoreId
= pNode
->mVarStoreId
;
1839 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1840 IN EFI_VARSTORE_ID VarStoreId
,
1841 OUT CHAR8
**DataTypeName
1844 SVfrVarStorageNode
*pNode
;
1846 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1847 return VFR_RETURN_FATAL_ERROR
;
1850 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1851 if (pNode
->mVarStoreId
== VarStoreId
) {
1852 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1853 return VFR_RETURN_SUCCESS
;
1857 return VFR_RETURN_UNDEFINED
;
1860 EFI_VFR_VARSTORE_TYPE
1861 CVfrDataStorage::GetVarStoreType (
1862 IN EFI_VARSTORE_ID VarStoreId
1865 SVfrVarStorageNode
*pNode
;
1866 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1868 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1870 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1871 return VarStoreType
;
1874 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1875 if (pNode
->mVarStoreId
== VarStoreId
) {
1876 VarStoreType
= pNode
->mVarStoreType
;
1877 return VarStoreType
;
1881 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1882 if (pNode
->mVarStoreId
== VarStoreId
) {
1883 VarStoreType
= pNode
->mVarStoreType
;
1884 return VarStoreType
;
1888 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1889 if (pNode
->mVarStoreId
== VarStoreId
) {
1890 VarStoreType
= pNode
->mVarStoreType
;
1891 return VarStoreType
;
1895 return VarStoreType
;
1899 CVfrDataStorage::GetVarStoreGuid (
1900 IN EFI_VARSTORE_ID VarStoreId
1903 SVfrVarStorageNode
*pNode
;
1908 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1912 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1913 if (pNode
->mVarStoreId
== VarStoreId
) {
1914 VarGuid
= &pNode
->mGuid
;
1919 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1920 if (pNode
->mVarStoreId
== VarStoreId
) {
1921 VarGuid
= &pNode
->mGuid
;
1926 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1927 if (pNode
->mVarStoreId
== VarStoreId
) {
1928 VarGuid
= &pNode
->mGuid
;
1937 CVfrDataStorage::GetVarStoreName (
1938 IN EFI_VARSTORE_ID VarStoreId
,
1939 OUT CHAR8
**VarStoreName
1942 SVfrVarStorageNode
*pNode
;
1944 if (VarStoreName
== NULL
) {
1945 return VFR_RETURN_FATAL_ERROR
;
1948 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1949 if (pNode
->mVarStoreId
== VarStoreId
) {
1950 *VarStoreName
= pNode
->mVarStoreName
;
1951 return VFR_RETURN_SUCCESS
;
1955 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1956 if (pNode
->mVarStoreId
== VarStoreId
) {
1957 *VarStoreName
= pNode
->mVarStoreName
;
1958 return VFR_RETURN_SUCCESS
;
1962 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1963 if (pNode
->mVarStoreId
== VarStoreId
) {
1964 *VarStoreName
= pNode
->mVarStoreName
;
1965 return VFR_RETURN_SUCCESS
;
1969 *VarStoreName
= NULL
;
1970 return VFR_RETURN_UNDEFINED
;
1974 CVfrDataStorage::GetEfiVarStoreInfo (
1975 IN OUT EFI_VARSTORE_INFO
*Info
1979 return VFR_RETURN_FATAL_ERROR
;
1982 if (mCurrVarStorageNode
== NULL
) {
1983 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1986 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1987 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1988 switch (Info
->mVarTotalSize
) {
1990 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1993 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1996 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1999 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
2002 return VFR_RETURN_FATAL_ERROR
;
2005 return VFR_RETURN_SUCCESS
;
2009 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2010 IN EFI_VARSTORE_INFO
*Info
2013 BufferVarStoreFieldInfoNode
*pNew
;
2015 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2016 return VFR_RETURN_FATAL_ERROR
;
2019 if (mBufferFieldInfoListHead
== NULL
) {
2020 mBufferFieldInfoListHead
= pNew
;
2021 mBufferFieldInfoListTail
= pNew
;
2023 mBufferFieldInfoListTail
->mNext
= pNew
;
2024 mBufferFieldInfoListTail
= pNew
;
2027 return VFR_RETURN_SUCCESS
;
2031 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2032 IN OUT EFI_VARSTORE_INFO
*Info
2035 BufferVarStoreFieldInfoNode
*pNode
;
2037 pNode
= mBufferFieldInfoListHead
;
2038 while (pNode
!= NULL
) {
2039 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2040 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2041 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2042 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2043 return VFR_RETURN_SUCCESS
;
2045 pNode
= pNode
->mNext
;
2047 return VFR_RETURN_FATAL_ERROR
;
2051 CVfrDataStorage::GetNameVarStoreInfo (
2052 OUT EFI_VARSTORE_INFO
*Info
,
2057 return VFR_RETURN_FATAL_ERROR
;
2060 if (mCurrVarStorageNode
== NULL
) {
2061 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2065 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2067 if (VfrCompatibleMode
) {
2069 return VFR_RETURN_ERROR_ARRARY_NUM
;
2074 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2076 return VFR_RETURN_SUCCESS
;
2079 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2080 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2082 IN EFI_STRING_ID DefaultStoreNameId
,
2086 mObjBinAddr
= ObjBinAddr
;
2088 if (RefName
!= NULL
) {
2089 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2090 strcpy (mRefName
, RefName
);
2096 mDefaultId
= DefaultId
;
2097 mDefaultStoreNameId
= DefaultStoreNameId
;
2100 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2104 if (mRefName
!= NULL
) {
2109 CVfrDefaultStore::CVfrDefaultStore (
2113 mDefaultStoreList
= NULL
;
2116 CVfrDefaultStore::~CVfrDefaultStore (
2120 SVfrDefaultStoreNode
*pTmp
= NULL
;
2122 while (mDefaultStoreList
!= NULL
) {
2123 pTmp
= mDefaultStoreList
;
2124 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2130 CVfrDefaultStore::RegisterDefaultStore (
2131 IN CHAR8
*ObjBinAddr
,
2133 IN EFI_STRING_ID DefaultStoreNameId
,
2137 SVfrDefaultStoreNode
*pNode
= NULL
;
2139 if (RefName
== NULL
) {
2140 return VFR_RETURN_FATAL_ERROR
;
2143 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2144 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2145 return VFR_RETURN_REDEFINED
;
2149 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2150 return VFR_RETURN_OUT_FOR_RESOURCES
;
2153 pNode
->mNext
= mDefaultStoreList
;
2154 mDefaultStoreList
= pNode
;
2156 return VFR_RETURN_SUCCESS
;
2160 * assign new reference name or new default store name id only if
2161 * the original is invalid
2164 CVfrDefaultStore::ReRegisterDefaultStoreById (
2165 IN UINT16 DefaultId
,
2167 IN EFI_STRING_ID DefaultStoreNameId
2170 SVfrDefaultStoreNode
*pNode
= NULL
;
2172 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2173 if (pNode
->mDefaultId
== DefaultId
) {
2178 if (pNode
== NULL
) {
2179 return VFR_RETURN_UNDEFINED
;
2181 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2182 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2183 if (pNode
->mObjBinAddr
!= NULL
) {
2184 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2187 return VFR_RETURN_REDEFINED
;
2190 if (RefName
!= NULL
) {
2191 delete pNode
->mRefName
;
2192 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2193 if (pNode
->mRefName
!= NULL
) {
2194 strcpy (pNode
->mRefName
, RefName
);
2199 return VFR_RETURN_SUCCESS
;
2203 CVfrDefaultStore::DefaultIdRegistered (
2207 SVfrDefaultStoreNode
*pNode
= NULL
;
2209 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2210 if (pNode
->mDefaultId
== DefaultId
) {
2219 CVfrDefaultStore::GetDefaultId (
2221 OUT UINT16
*DefaultId
2224 SVfrDefaultStoreNode
*pTmp
= NULL
;
2226 if (DefaultId
== NULL
) {
2227 return VFR_RETURN_FATAL_ERROR
;
2230 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2231 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2232 *DefaultId
= pTmp
->mDefaultId
;
2233 return VFR_RETURN_SUCCESS
;
2237 return VFR_RETURN_UNDEFINED
;
2241 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2242 IN EFI_VARSTORE_ID DefaultId
,
2243 IN EFI_VARSTORE_INFO
&Info
,
2244 IN CHAR8
*VarStoreName
,
2245 IN EFI_GUID
*VarStoreGuid
,
2247 IN EFI_IFR_TYPE_VALUE Value
2250 SVfrDefaultStoreNode
*pNode
= NULL
;
2251 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2252 INTN Returnvalue
= 0;
2254 if (VarStoreName
== NULL
) {
2255 return VFR_RETURN_FATAL_ERROR
;
2258 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2259 if (pNode
->mDefaultId
== DefaultId
) {
2264 if (pNode
== NULL
) {
2265 return VFR_RETURN_UNDEFINED
;
2268 gCVfrBufferConfig
.Open ();
2270 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2271 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2272 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2277 gCVfrBufferConfig
.Close ();
2279 return VFR_RETURN_SUCCESS
;
2282 gCVfrBufferConfig
.Close ();
2283 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2286 SVfrRuleNode::SVfrRuleNode (
2291 if (RuleName
!= NULL
) {
2292 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2293 strcpy (mRuleName
, RuleName
);
2302 SVfrRuleNode::~SVfrRuleNode (
2306 if (mRuleName
!= NULL
) {
2311 CVfrRulesDB::CVfrRulesDB ()
2314 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2317 CVfrRulesDB::~CVfrRulesDB ()
2319 SVfrRuleNode
*pNode
;
2321 while(mRuleList
!= NULL
) {
2323 mRuleList
= mRuleList
->mNext
;
2329 CVfrRulesDB::RegisterRule (
2335 if (RuleName
== NULL
) {
2339 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2345 pNew
->mNext
= mRuleList
;
2350 CVfrRulesDB::GetRuleId (
2354 SVfrRuleNode
*pNode
;
2356 if (RuleName
== NULL
) {
2357 return EFI_RULE_ID_INVALID
;
2360 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2361 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2362 return pNode
->mRuleId
;
2366 return EFI_RULE_ID_INVALID
;
2369 CVfrRulesDB gCVfrRulesDB
;
2371 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2375 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2376 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2377 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2378 mVarType
= EFI_IFR_TYPE_OTHER
;
2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2383 IN EFI_VARSTORE_INFO
&Info
2386 mVarStoreId
= Info
.mVarStoreId
;
2387 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2388 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2389 mVarType
= Info
.mVarType
;
2390 mVarTotalSize
= Info
.mVarTotalSize
;
2394 EFI_VARSTORE_INFO::operator= (
2395 IN CONST EFI_VARSTORE_INFO
&Info
2398 if (this != &Info
) {
2399 mVarStoreId
= Info
.mVarStoreId
;
2400 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2401 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2402 mVarType
= Info
.mVarType
;
2403 mVarTotalSize
= Info
.mVarTotalSize
;
2410 EFI_VARSTORE_INFO::operator == (
2411 IN EFI_VARSTORE_INFO
*Info
2414 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2415 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2416 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2417 (mVarType
== Info
->mVarType
) &&
2418 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2425 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2426 IN EFI_VARSTORE_INFO
*Info
2429 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2430 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2431 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2432 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2436 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2438 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2439 mVarStoreInfo
.mVarTotalSize
= 0;
2440 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2441 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2445 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2448 CVfrQuestionDB::GetFreeQuestionId (
2452 UINT32 Index
, Mask
, Offset
;
2454 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2455 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2460 if (Index
== EFI_FREE_QUESTION_ID_BITMAP_SIZE
) {
2461 return EFI_QUESTION_ID_INVALID
;
2464 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2465 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2466 mFreeQIdBitMap
[Index
] |= Mask
;
2467 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2471 return EFI_QUESTION_ID_INVALID
;
2475 CVfrQuestionDB::ChekQuestionIdFree (
2476 IN EFI_QUESTION_ID QId
2479 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2480 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2482 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2486 CVfrQuestionDB::MarkQuestionIdUsed (
2487 IN EFI_QUESTION_ID QId
2490 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2491 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2493 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2497 CVfrQuestionDB::MarkQuestionIdUnused (
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
);
2507 SVfrQuestionNode::SVfrQuestionNode (
2515 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2518 mQtype
= QUESTION_NORMAL
;
2521 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2522 strcpy (mName
, "$DEFAULT");
2524 mName
= new CHAR8
[strlen (Name
) + 1];
2525 strcpy (mName
, Name
);
2528 if (VarIdStr
!= NULL
) {
2529 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2530 strcpy (mVarIdStr
, VarIdStr
);
2532 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2533 strcpy (mVarIdStr
, "$");
2537 SVfrQuestionNode::~SVfrQuestionNode (
2541 if (mName
!= NULL
) {
2545 if (mVarIdStr
!= NULL
) {
2550 CVfrQuestionDB::CVfrQuestionDB ()
2554 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2555 mFreeQIdBitMap
[Index
] = 0;
2558 // Question ID 0 is reserved.
2559 mFreeQIdBitMap
[0] = 0x80000000;
2560 mQuestionList
= NULL
;
2563 CVfrQuestionDB::~CVfrQuestionDB ()
2565 SVfrQuestionNode
*pNode
;
2567 while (mQuestionList
!= NULL
) {
2568 pNode
= mQuestionList
;
2569 mQuestionList
= mQuestionList
->mNext
;
2575 // Reset to init state
2578 CVfrQuestionDB::ResetInit(
2583 SVfrQuestionNode
*pNode
;
2585 while (mQuestionList
!= NULL
) {
2586 pNode
= mQuestionList
;
2587 mQuestionList
= mQuestionList
->mNext
;
2591 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2592 mFreeQIdBitMap
[Index
] = 0;
2595 // Question ID 0 is reserved.
2596 mFreeQIdBitMap
[0] = 0x80000000;
2597 mQuestionList
= NULL
;
2601 CVfrQuestionDB::PrintAllQuestion (
2605 SVfrQuestionNode
*pNode
= NULL
;
2607 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2608 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2613 CVfrQuestionDB::RegisterQuestion (
2616 IN OUT EFI_QUESTION_ID
&QuestionId
2619 SVfrQuestionNode
*pNode
= NULL
;
2621 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2622 return VFR_RETURN_REDEFINED
;
2625 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2626 return VFR_RETURN_OUT_FOR_RESOURCES
;
2629 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2630 QuestionId
= GetFreeQuestionId ();
2633 // For Framework Vfr, don't check question ID conflict.
2635 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2637 return VFR_RETURN_QUESTIONID_REDEFINED
;
2639 MarkQuestionIdUsed (QuestionId
);
2641 pNode
->mQuestionId
= QuestionId
;
2643 pNode
->mNext
= mQuestionList
;
2644 mQuestionList
= pNode
;
2646 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2648 return VFR_RETURN_SUCCESS
;
2652 CVfrQuestionDB::RegisterOldDateQuestion (
2653 IN CHAR8
*YearVarId
,
2654 IN CHAR8
*MonthVarId
,
2656 IN OUT EFI_QUESTION_ID
&QuestionId
2659 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2662 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2666 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2669 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2672 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2676 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2677 QuestionId
= GetFreeQuestionId ();
2679 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2682 MarkQuestionIdUsed (QuestionId
);
2685 pNode
[0]->mQuestionId
= QuestionId
;
2686 pNode
[1]->mQuestionId
= QuestionId
;
2687 pNode
[2]->mQuestionId
= QuestionId
;
2688 pNode
[0]->mQtype
= QUESTION_DATE
;
2689 pNode
[1]->mQtype
= QUESTION_DATE
;
2690 pNode
[2]->mQtype
= QUESTION_DATE
;
2691 pNode
[0]->mNext
= pNode
[1];
2692 pNode
[1]->mNext
= pNode
[2];
2693 pNode
[2]->mNext
= mQuestionList
;
2694 mQuestionList
= pNode
[0];
2696 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2697 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2698 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2703 for (Index
= 0; Index
< 3; Index
++) {
2704 if (pNode
[Index
] != NULL
) {
2705 delete pNode
[Index
];
2708 QuestionId
= EFI_QUESTION_ID_INVALID
;
2712 CVfrQuestionDB::RegisterNewDateQuestion (
2714 IN CHAR8
*BaseVarId
,
2715 IN OUT EFI_QUESTION_ID
&QuestionId
2718 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2720 CHAR8
*VarIdStr
[3] = {NULL
, };
2723 if (BaseVarId
== NULL
&& Name
== NULL
) {
2724 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2725 QuestionId
= GetFreeQuestionId ();
2727 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2730 MarkQuestionIdUsed (QuestionId
);
2735 if (BaseVarId
!= NULL
) {
2736 Len
= strlen (BaseVarId
);
2738 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2739 if (VarIdStr
[0] != NULL
) {
2740 strcpy (VarIdStr
[0], BaseVarId
);
2741 strcat (VarIdStr
[0], ".Year");
2743 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2744 if (VarIdStr
[1] != NULL
) {
2745 strcpy (VarIdStr
[1], BaseVarId
);
2746 strcat (VarIdStr
[1], ".Month");
2748 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2749 if (VarIdStr
[2] != NULL
) {
2750 strcpy (VarIdStr
[2], BaseVarId
);
2751 strcat (VarIdStr
[2], ".Day");
2754 Len
= strlen (Name
);
2756 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2757 if (VarIdStr
[0] != NULL
) {
2758 strcpy (VarIdStr
[0], Name
);
2759 strcat (VarIdStr
[0], ".Year");
2761 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2762 if (VarIdStr
[1] != NULL
) {
2763 strcpy (VarIdStr
[1], Name
);
2764 strcat (VarIdStr
[1], ".Month");
2766 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2767 if (VarIdStr
[2] != NULL
) {
2768 strcpy (VarIdStr
[2], Name
);
2769 strcat (VarIdStr
[2], ".Day");
2773 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2776 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2779 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2783 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2784 QuestionId
= GetFreeQuestionId ();
2786 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2789 MarkQuestionIdUsed (QuestionId
);
2792 pNode
[0]->mQuestionId
= QuestionId
;
2793 pNode
[1]->mQuestionId
= QuestionId
;
2794 pNode
[2]->mQuestionId
= QuestionId
;
2795 pNode
[0]->mQtype
= QUESTION_DATE
;
2796 pNode
[1]->mQtype
= QUESTION_DATE
;
2797 pNode
[2]->mQtype
= QUESTION_DATE
;
2798 pNode
[0]->mNext
= pNode
[1];
2799 pNode
[1]->mNext
= pNode
[2];
2800 pNode
[2]->mNext
= mQuestionList
;
2801 mQuestionList
= pNode
[0];
2803 for (Index
= 0; Index
< 3; Index
++) {
2804 if (VarIdStr
[Index
] != NULL
) {
2805 delete VarIdStr
[Index
];
2809 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2810 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2811 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2816 for (Index
= 0; Index
< 3; Index
++) {
2817 if (pNode
[Index
] != NULL
) {
2818 delete pNode
[Index
];
2821 if (VarIdStr
[Index
] != NULL
) {
2822 delete VarIdStr
[Index
];
2828 CVfrQuestionDB::RegisterOldTimeQuestion (
2829 IN CHAR8
*HourVarId
,
2830 IN CHAR8
*MinuteVarId
,
2831 IN CHAR8
*SecondVarId
,
2832 IN OUT EFI_QUESTION_ID
&QuestionId
2835 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2838 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2842 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2845 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2848 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2852 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2853 QuestionId
= GetFreeQuestionId ();
2855 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2858 MarkQuestionIdUsed (QuestionId
);
2861 pNode
[0]->mQuestionId
= QuestionId
;
2862 pNode
[1]->mQuestionId
= QuestionId
;
2863 pNode
[2]->mQuestionId
= QuestionId
;
2864 pNode
[0]->mQtype
= QUESTION_TIME
;
2865 pNode
[1]->mQtype
= QUESTION_TIME
;
2866 pNode
[2]->mQtype
= QUESTION_TIME
;
2867 pNode
[0]->mNext
= pNode
[1];
2868 pNode
[1]->mNext
= pNode
[2];
2869 pNode
[2]->mNext
= mQuestionList
;
2870 mQuestionList
= pNode
[0];
2872 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2873 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2874 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2879 for (Index
= 0; Index
< 3; Index
++) {
2880 if (pNode
[Index
] != NULL
) {
2881 delete pNode
[Index
];
2884 QuestionId
= EFI_QUESTION_ID_INVALID
;
2888 CVfrQuestionDB::RegisterNewTimeQuestion (
2890 IN CHAR8
*BaseVarId
,
2891 IN OUT EFI_QUESTION_ID
&QuestionId
2894 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2896 CHAR8
*VarIdStr
[3] = {NULL
, };
2899 if (BaseVarId
== NULL
&& Name
== NULL
) {
2900 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2901 QuestionId
= GetFreeQuestionId ();
2903 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2906 MarkQuestionIdUsed (QuestionId
);
2911 if (BaseVarId
!= NULL
) {
2912 Len
= strlen (BaseVarId
);
2914 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2915 if (VarIdStr
[0] != NULL
) {
2916 strcpy (VarIdStr
[0], BaseVarId
);
2917 strcat (VarIdStr
[0], ".Hour");
2919 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2920 if (VarIdStr
[1] != NULL
) {
2921 strcpy (VarIdStr
[1], BaseVarId
);
2922 strcat (VarIdStr
[1], ".Minute");
2924 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2925 if (VarIdStr
[2] != NULL
) {
2926 strcpy (VarIdStr
[2], BaseVarId
);
2927 strcat (VarIdStr
[2], ".Second");
2930 Len
= strlen (Name
);
2932 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2933 if (VarIdStr
[0] != NULL
) {
2934 strcpy (VarIdStr
[0], Name
);
2935 strcat (VarIdStr
[0], ".Hour");
2937 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2938 if (VarIdStr
[1] != NULL
) {
2939 strcpy (VarIdStr
[1], Name
);
2940 strcat (VarIdStr
[1], ".Minute");
2942 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2943 if (VarIdStr
[2] != NULL
) {
2944 strcpy (VarIdStr
[2], Name
);
2945 strcat (VarIdStr
[2], ".Second");
2949 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2952 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2955 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2959 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2960 QuestionId
= GetFreeQuestionId ();
2962 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2965 MarkQuestionIdUsed (QuestionId
);
2968 pNode
[0]->mQuestionId
= QuestionId
;
2969 pNode
[1]->mQuestionId
= QuestionId
;
2970 pNode
[2]->mQuestionId
= QuestionId
;
2971 pNode
[0]->mQtype
= QUESTION_TIME
;
2972 pNode
[1]->mQtype
= QUESTION_TIME
;
2973 pNode
[2]->mQtype
= QUESTION_TIME
;
2974 pNode
[0]->mNext
= pNode
[1];
2975 pNode
[1]->mNext
= pNode
[2];
2976 pNode
[2]->mNext
= mQuestionList
;
2977 mQuestionList
= pNode
[0];
2979 for (Index
= 0; Index
< 3; Index
++) {
2980 if (VarIdStr
[Index
] != NULL
) {
2981 delete VarIdStr
[Index
];
2985 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2986 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2987 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2992 for (Index
= 0; Index
< 3; Index
++) {
2993 if (pNode
[Index
] != NULL
) {
2994 delete pNode
[Index
];
2997 if (VarIdStr
[Index
] != NULL
) {
2998 delete VarIdStr
[Index
];
3004 CVfrQuestionDB::RegisterRefQuestion (
3006 IN CHAR8
*BaseVarId
,
3007 IN OUT EFI_QUESTION_ID
&QuestionId
3010 SVfrQuestionNode
*pNode
[4] = {NULL
, };
3012 CHAR8
*VarIdStr
[4] = {NULL
, };
3015 if (BaseVarId
== NULL
&& Name
== NULL
) {
3019 if (BaseVarId
!= NULL
) {
3020 Len
= strlen (BaseVarId
);
3022 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3023 if (VarIdStr
[0] != NULL
) {
3024 strcpy (VarIdStr
[0], BaseVarId
);
3025 strcat (VarIdStr
[0], ".QuestionId");
3027 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3028 if (VarIdStr
[1] != NULL
) {
3029 strcpy (VarIdStr
[1], BaseVarId
);
3030 strcat (VarIdStr
[1], ".FormId");
3032 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3033 if (VarIdStr
[2] != NULL
) {
3034 strcpy (VarIdStr
[2], BaseVarId
);
3035 strcat (VarIdStr
[2], ".FormSetGuid");
3037 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3038 if (VarIdStr
[3] != NULL
) {
3039 strcpy (VarIdStr
[3], BaseVarId
);
3040 strcat (VarIdStr
[3], ".DevicePath");
3043 Len
= strlen (Name
);
3045 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3046 if (VarIdStr
[0] != NULL
) {
3047 strcpy (VarIdStr
[0], Name
);
3048 strcat (VarIdStr
[0], ".QuestionId");
3050 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3051 if (VarIdStr
[1] != NULL
) {
3052 strcpy (VarIdStr
[1], Name
);
3053 strcat (VarIdStr
[1], ".FormId");
3055 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3056 if (VarIdStr
[2] != NULL
) {
3057 strcpy (VarIdStr
[2], Name
);
3058 strcat (VarIdStr
[2], ".FormSetGuid");
3060 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3061 if (VarIdStr
[3] != NULL
) {
3062 strcpy (VarIdStr
[3], Name
);
3063 strcat (VarIdStr
[3], ".DevicePath");
3067 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3070 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3073 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3076 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3080 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3081 QuestionId
= GetFreeQuestionId ();
3083 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3086 MarkQuestionIdUsed (QuestionId
);
3089 pNode
[0]->mQuestionId
= QuestionId
;
3090 pNode
[1]->mQuestionId
= QuestionId
;
3091 pNode
[2]->mQuestionId
= QuestionId
;
3092 pNode
[3]->mQuestionId
= QuestionId
;
3093 pNode
[0]->mQtype
= QUESTION_REF
;
3094 pNode
[1]->mQtype
= QUESTION_REF
;
3095 pNode
[2]->mQtype
= QUESTION_REF
;
3096 pNode
[3]->mQtype
= QUESTION_REF
;
3097 pNode
[0]->mNext
= pNode
[1];
3098 pNode
[1]->mNext
= pNode
[2];
3099 pNode
[2]->mNext
= pNode
[3];
3100 pNode
[3]->mNext
= mQuestionList
;
3101 mQuestionList
= pNode
[0];
3103 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3104 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3105 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3106 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3111 for (Index
= 0; Index
< 4; Index
++) {
3112 if (pNode
[Index
] != NULL
) {
3113 delete pNode
[Index
];
3116 if (VarIdStr
[Index
] != NULL
) {
3117 delete VarIdStr
[Index
];
3123 CVfrQuestionDB::UpdateQuestionId (
3124 IN EFI_QUESTION_ID QId
,
3125 IN EFI_QUESTION_ID NewQId
3128 SVfrQuestionNode
*pNode
= NULL
;
3130 if (QId
== NewQId
) {
3132 return VFR_RETURN_SUCCESS
;
3136 // For Framework Vfr, don't check question ID conflict.
3138 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3139 return VFR_RETURN_REDEFINED
;
3142 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3143 if (pNode
->mQuestionId
== QId
) {
3148 if (pNode
== NULL
) {
3149 return VFR_RETURN_UNDEFINED
;
3152 MarkQuestionIdUnused (QId
);
3153 pNode
->mQuestionId
= NewQId
;
3154 MarkQuestionIdUsed (NewQId
);
3156 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3158 return VFR_RETURN_SUCCESS
;
3162 CVfrQuestionDB::GetQuestionId (
3165 OUT EFI_QUESTION_ID
&QuestionId
,
3166 OUT UINT32
&BitMask
,
3167 OUT EFI_QUESION_TYPE
*QType
3170 SVfrQuestionNode
*pNode
;
3172 QuestionId
= EFI_QUESTION_ID_INVALID
;
3173 BitMask
= 0x00000000;
3174 if (QType
!= NULL
) {
3175 *QType
= QUESTION_NORMAL
;
3178 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3182 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3184 if (strcmp (pNode
->mName
, Name
) != 0) {
3189 if (VarIdStr
!= NULL
) {
3190 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3195 QuestionId
= pNode
->mQuestionId
;
3196 BitMask
= pNode
->mBitMask
;
3197 if (QType
!= NULL
) {
3198 *QType
= pNode
->mQtype
;
3207 CVfrQuestionDB::FindQuestion (
3208 IN EFI_QUESTION_ID QuestionId
3211 SVfrQuestionNode
*pNode
;
3213 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3214 return VFR_RETURN_INVALID_PARAMETER
;
3217 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3218 if (pNode
->mQuestionId
== QuestionId
) {
3219 return VFR_RETURN_SUCCESS
;
3223 return VFR_RETURN_UNDEFINED
;
3227 CVfrQuestionDB::FindQuestion (
3231 SVfrQuestionNode
*pNode
;
3234 return VFR_RETURN_FATAL_ERROR
;
3237 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3238 if (strcmp (pNode
->mName
, Name
) == 0) {
3239 return VFR_RETURN_SUCCESS
;
3243 return VFR_RETURN_UNDEFINED
;
3246 CVfrStringDB::CVfrStringDB ()
3248 mStringFileName
= NULL
;
3251 CVfrStringDB::~CVfrStringDB ()
3253 if (mStringFileName
!= NULL
) {
3254 delete mStringFileName
;
3256 mStringFileName
= NULL
;
3261 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3265 if (StringFileName
== NULL
) {
3269 FileLen
= strlen (StringFileName
) + 1;
3270 mStringFileName
= new CHAR8
[FileLen
];
3271 if (mStringFileName
== NULL
) {
3275 strcpy (mStringFileName
, StringFileName
);
3276 mStringFileName
[FileLen
- 1] = '\0';
3281 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3282 from a set of supported languages.
3284 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3285 contains a set of language codes.
3286 @param[in] Language A variable that contains pointers to Null-terminated
3287 ASCII strings that contain one language codes.
3289 @retval FALSE The best matching language could not be found in SupportedLanguages.
3290 @retval TRUE The best matching language could be found in SupportedLanguages.
3294 CVfrStringDB::GetBestLanguage (
3295 IN CONST CHAR8
*SupportedLanguages
,
3299 UINTN CompareLength
;
3300 UINTN LanguageLength
;
3301 CONST CHAR8
*Supported
;
3303 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3308 // Determine the length of the first RFC 4646 language code in Language
3310 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3313 // Trim back the length of Language used until it is empty
3315 while (LanguageLength
> 0) {
3317 // Loop through all language codes in SupportedLanguages
3319 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3321 // Skip ';' characters in Supported
3323 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3325 // Determine the length of the next language code in Supported
3327 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3329 // If Language is longer than the Supported, then skip to the next language
3331 if (LanguageLength
> CompareLength
) {
3336 // See if the first LanguageLength characters in Supported match Language
3338 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3344 // Trim Language from the right to the next '-' character
3346 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3350 // No matches were found
3357 CVfrStringDB::GetVarStoreNameFormStringId (
3358 IN EFI_STRING_ID StringId
3361 FILE *pInFile
= NULL
;
3366 CHAR16
*UnicodeString
;
3367 CHAR8
*VarStoreName
= NULL
;
3371 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3373 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3375 if (mStringFileName
== '\0' ) {
3379 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3386 fseek (pInFile
, 0, SEEK_END
);
3387 Length
= ftell (pInFile
);
3388 fseek (pInFile
, 0, SEEK_SET
);
3393 StringPtr
= new UINT8
[Length
];
3394 if (StringPtr
== NULL
) {
3398 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3401 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3403 // Check the String package.
3405 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3411 // Search the language, get best language base on RFC 4647 matching algorithm.
3413 Current
= StringPtr
;
3414 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3415 Current
+= PkgHeader
->Header
.Length
;
3416 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3418 // If can't find string package base on language, just return the first string package.
3420 if (Current
- StringPtr
>= Length
) {
3421 Current
= StringPtr
;
3422 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3427 Current
+= PkgHeader
->HdrSize
;
3429 // Find the string block according the stringId.
3431 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3432 if (Status
!= EFI_SUCCESS
) {
3438 // Get varstore name according the string type.
3440 switch (BlockType
) {
3441 case EFI_HII_SIBT_STRING_SCSU
:
3442 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3443 case EFI_HII_SIBT_STRINGS_SCSU
:
3444 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3445 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3446 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3447 strcpy (VarStoreName
, StringName
);
3449 case EFI_HII_SIBT_STRING_UCS2
:
3450 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3451 case EFI_HII_SIBT_STRINGS_UCS2
:
3452 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3453 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3454 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3455 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3456 VarStoreName
= DestTmp
;
3457 while (*UnicodeString
!= '\0') {
3458 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3468 return VarStoreName
;
3472 CVfrStringDB::FindStringBlock (
3473 IN UINT8
*StringData
,
3474 IN EFI_STRING_ID StringId
,
3475 OUT UINT32
*StringTextOffset
,
3476 OUT UINT8
*BlockType
3480 EFI_STRING_ID CurrentStringId
;
3483 UINT8
*StringTextPtr
;
3488 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3492 CurrentStringId
= 1;
3495 // Parse the string blocks to get the string text and font.
3497 BlockHdr
= StringData
;
3500 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3501 switch (*BlockHdr
) {
3502 case EFI_HII_SIBT_STRING_SCSU
:
3503 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3504 StringTextPtr
= BlockHdr
+ Offset
;
3505 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3509 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3510 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3511 StringTextPtr
= BlockHdr
+ Offset
;
3512 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3516 case EFI_HII_SIBT_STRINGS_SCSU
:
3517 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3518 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3519 BlockSize
+= StringTextPtr
- BlockHdr
;
3521 for (Index
= 0; Index
< StringCount
; Index
++) {
3522 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3523 if (CurrentStringId
== StringId
) {
3524 *BlockType
= *BlockHdr
;
3525 *StringTextOffset
= StringTextPtr
- StringData
;
3528 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3533 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3536 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3539 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3540 BlockSize
+= StringTextPtr
- BlockHdr
;
3542 for (Index
= 0; Index
< StringCount
; Index
++) {
3543 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3544 if (CurrentStringId
== StringId
) {
3545 *BlockType
= *BlockHdr
;
3546 *StringTextOffset
= StringTextPtr
- StringData
;
3549 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3554 case EFI_HII_SIBT_STRING_UCS2
:
3555 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3556 StringTextPtr
= BlockHdr
+ Offset
;
3558 // Use StringSize to store the size of the specified string, including the NULL
3561 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3562 BlockSize
+= Offset
+ StringSize
;
3566 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3567 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3568 StringTextPtr
= BlockHdr
+ Offset
;
3570 // Use StrSize to store the size of the specified string, including the NULL
3573 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3574 BlockSize
+= Offset
+ StringSize
;
3578 case EFI_HII_SIBT_STRINGS_UCS2
:
3579 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3580 StringTextPtr
= BlockHdr
+ Offset
;
3581 BlockSize
+= Offset
;
3582 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3583 for (Index
= 0; Index
< StringCount
; Index
++) {
3584 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3585 BlockSize
+= StringSize
;
3586 if (CurrentStringId
== StringId
) {
3587 *BlockType
= *BlockHdr
;
3588 *StringTextOffset
= StringTextPtr
- StringData
;
3591 StringTextPtr
= StringTextPtr
+ StringSize
;
3596 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3597 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3598 StringTextPtr
= BlockHdr
+ Offset
;
3599 BlockSize
+= Offset
;
3602 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3605 for (Index
= 0; Index
< StringCount
; Index
++) {
3606 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3607 BlockSize
+= StringSize
;
3608 if (CurrentStringId
== StringId
) {
3609 *BlockType
= *BlockHdr
;
3610 *StringTextOffset
= StringTextPtr
- StringData
;
3613 StringTextPtr
= StringTextPtr
+ StringSize
;
3618 case EFI_HII_SIBT_DUPLICATE
:
3619 if (CurrentStringId
== StringId
) {
3621 // Incoming StringId is an id of a duplicate string block.
3622 // Update the StringId to be the previous string block.
3623 // Go back to the header of string block to search.
3627 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3628 sizeof (EFI_STRING_ID
)
3630 CurrentStringId
= 1;
3633 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3638 case EFI_HII_SIBT_SKIP1
:
3639 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3640 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3641 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3644 case EFI_HII_SIBT_SKIP2
:
3645 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3646 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3647 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3650 case EFI_HII_SIBT_EXT1
:
3653 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3656 BlockSize
+= Length8
;
3659 case EFI_HII_SIBT_EXT2
:
3660 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3661 BlockSize
+= Ext2
.Length
;
3664 case EFI_HII_SIBT_EXT4
:
3667 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3671 BlockSize
+= Length32
;
3678 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3679 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3680 *BlockType
= *BlockHdr
;
3682 if (StringId
== CurrentStringId
- 1) {
3684 // if only one skip item, return EFI_NOT_FOUND.
3686 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3687 return EFI_NOT_FOUND
;
3693 if (StringId
< CurrentStringId
- 1) {
3694 return EFI_NOT_FOUND
;
3697 BlockHdr
= StringData
+ BlockSize
;
3700 return EFI_NOT_FOUND
;
3704 CVfrStringDB::GetUnicodeStringTextSize (
3711 StringSize
= sizeof (CHAR16
);
3712 StringPtr
= (UINT16
*)StringSrc
;
3713 while (*StringPtr
++ != L
'\0') {
3714 StringSize
+= sizeof (CHAR16
);
3720 BOOLEAN VfrCompatibleMode
= FALSE
;
3722 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3723 CVfrDefaultStore gCVfrDefaultStore
;
3724 CVfrDataStorage gCVfrDataStorage
;