3 Vfr common library functions.
5 Copyright (c) 2004 - 2015, 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 BUFFER_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 BUFFER_SAFE_FREE (mName
);
204 BUFFER_SAFE_FREE (mGuid
);
205 BUFFER_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 (&Guid
, 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 (&Guid
, 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
;
1424 CVfrDataStorage::~CVfrDataStorage (
1428 SVfrVarStorageNode
*pNode
;
1430 while (mBufferVarStoreList
!= NULL
) {
1431 pNode
= mBufferVarStoreList
;
1432 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1435 while (mEfiVarStoreList
!= NULL
) {
1436 pNode
= mEfiVarStoreList
;
1437 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1440 while (mNameVarStoreList
!= NULL
) {
1441 pNode
= mNameVarStoreList
;
1442 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1445 if (mNewVarStorageNode
!= NULL
) {
1446 delete mNewVarStorageNode
;
1451 CVfrDataStorage::GetFreeVarStoreId (
1452 EFI_VFR_VARSTORE_TYPE VarType
1455 UINT32 Index
, Mask
, Offset
;
1458 // Assign the different ID range for the different type VarStore to support Framework Vfr
1461 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1463 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1465 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1469 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1470 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1475 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1476 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1477 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1478 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1482 return EFI_VARSTORE_ID_INVALID
;
1486 CVfrDataStorage::ChekVarStoreIdFree (
1487 IN EFI_VARSTORE_ID VarStoreId
1490 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1491 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1493 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1497 CVfrDataStorage::MarkVarStoreIdUsed (
1498 IN EFI_VARSTORE_ID VarStoreId
1501 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1502 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1504 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1508 CVfrDataStorage::MarkVarStoreIdUnused (
1509 IN EFI_VARSTORE_ID VarStoreId
1512 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1513 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1515 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1519 CVfrDataStorage::DeclareNameVarStoreBegin (
1520 IN CHAR8
*StoreName
,
1521 IN EFI_VARSTORE_ID VarStoreId
1524 SVfrVarStorageNode
*pNode
= NULL
;
1525 EFI_VARSTORE_ID TmpVarStoreId
;
1527 if (StoreName
== NULL
) {
1528 return VFR_RETURN_FATAL_ERROR
;
1531 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1532 return VFR_RETURN_REDEFINED
;
1535 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1536 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1538 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1539 return VFR_RETURN_VARSTOREID_REDEFINED
;
1541 MarkVarStoreIdUsed (VarStoreId
);
1544 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1545 return VFR_RETURN_UNDEFINED
;
1548 mNewVarStorageNode
= pNode
;
1550 return VFR_RETURN_SUCCESS
;
1554 CVfrDataStorage::NameTableAddItem (
1555 IN EFI_STRING_ID Item
1558 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1561 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1562 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1564 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1565 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1566 return VFR_RETURN_OUT_FOR_RESOURCES
;
1568 memcpy (NewTable
, OldTable
, TableSize
);
1569 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1572 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1573 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1575 return VFR_RETURN_SUCCESS
;
1579 CVfrDataStorage::DeclareNameVarStoreEnd (
1583 mNewVarStorageNode
->mGuid
= *Guid
;
1584 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1585 mNameVarStoreList
= mNewVarStorageNode
;
1587 mNewVarStorageNode
= NULL
;
1589 return VFR_RETURN_SUCCESS
;
1593 CVfrDataStorage::DeclareEfiVarStore (
1594 IN CHAR8
*StoreName
,
1596 IN EFI_STRING_ID NameStrId
,
1601 SVfrVarStorageNode
*pNode
;
1602 EFI_VARSTORE_ID VarStoreId
;
1604 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1605 return VFR_RETURN_FATAL_ERROR
;
1608 if (VarSize
> sizeof (UINT64
)) {
1609 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1612 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1613 return VFR_RETURN_REDEFINED
;
1616 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1617 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1618 return VFR_RETURN_OUT_FOR_RESOURCES
;
1621 pNode
->mNext
= mEfiVarStoreList
;
1622 mEfiVarStoreList
= pNode
;
1624 return VFR_RETURN_SUCCESS
;
1628 CVfrDataStorage::DeclareBufferVarStore (
1629 IN CHAR8
*StoreName
,
1631 IN CVfrVarDataTypeDB
*DataTypeDB
,
1633 IN EFI_VARSTORE_ID VarStoreId
,
1637 SVfrVarStorageNode
*pNew
= NULL
;
1638 SVfrDataType
*pDataType
= NULL
;
1639 EFI_VARSTORE_ID TempVarStoreId
;
1641 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1642 return VFR_RETURN_FATAL_ERROR
;
1645 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1646 return VFR_RETURN_REDEFINED
;
1649 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1651 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1652 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1654 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1655 return VFR_RETURN_VARSTOREID_REDEFINED
;
1657 MarkVarStoreIdUsed (VarStoreId
);
1660 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1661 return VFR_RETURN_OUT_FOR_RESOURCES
;
1664 pNew
->mNext
= mBufferVarStoreList
;
1665 mBufferVarStoreList
= pNew
;
1667 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1668 return VFR_RETURN_FATAL_ERROR
;
1671 return VFR_RETURN_SUCCESS
;
1675 CVfrDataStorage::GetVarStoreByDataType (
1676 IN CHAR8
*DataTypeName
,
1677 OUT SVfrVarStorageNode
**VarNode
,
1678 IN EFI_GUID
*VarGuid
1681 SVfrVarStorageNode
*pNode
;
1682 SVfrVarStorageNode
*MatchNode
;
1685 // Framework VFR uses Data type name as varstore name, so don't need check again.
1687 if (VfrCompatibleMode
) {
1688 return VFR_RETURN_UNDEFINED
;
1692 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1693 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1697 if ((VarGuid
!= NULL
)) {
1698 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1700 return VFR_RETURN_SUCCESS
;
1703 if (MatchNode
== NULL
) {
1707 // More than one varstores referred the same data structures.
1709 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1714 if (MatchNode
== NULL
) {
1715 return VFR_RETURN_UNDEFINED
;
1718 *VarNode
= MatchNode
;
1719 return VFR_RETURN_SUCCESS
;
1723 CVfrDataStorage::CheckGuidField (
1724 IN SVfrVarStorageNode
*pNode
,
1725 IN EFI_GUID
*StoreGuid
,
1726 IN BOOLEAN
*HasFoundOne
,
1727 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1730 if (StoreGuid
!= NULL
) {
1732 // If has guid info, compare the guid filed.
1734 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1736 // Both name and guid are same, this this varstore.
1738 mCurrVarStorageNode
= pNode
;
1739 *ReturnCode
= VFR_RETURN_SUCCESS
;
1744 // Not has Guid field, check whether this name is the only one.
1748 // The name has conflict, return name redefined.
1750 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1754 *HasFoundOne
= TRUE
;
1755 mCurrVarStorageNode
= pNode
;
1762 Base on the input store name and guid to find the varstore id.
1764 If both name and guid are inputed, base on the name and guid to
1765 found the varstore. If only name inputed, base on the name to
1766 found the varstore and go on to check whether more than one varstore
1767 has the same name. If only has found one varstore, return this
1768 varstore; if more than one varstore has same name, return varstore
1769 name redefined error. If no varstore found by varstore name, call
1770 function GetVarStoreByDataType and use inputed varstore name as
1771 data type name to search.
1774 CVfrDataStorage::GetVarStoreId (
1775 IN CHAR8
*StoreName
,
1776 OUT EFI_VARSTORE_ID
*VarStoreId
,
1777 IN EFI_GUID
*StoreGuid
1780 EFI_VFR_RETURN_CODE ReturnCode
;
1781 SVfrVarStorageNode
*pNode
;
1782 BOOLEAN HasFoundOne
= FALSE
;
1784 mCurrVarStorageNode
= NULL
;
1786 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1787 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1788 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1789 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1795 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1796 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1797 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1798 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1804 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1805 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1806 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1807 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1814 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1815 return VFR_RETURN_SUCCESS
;
1818 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1821 // Assume that Data strucutre name is used as StoreName, and check again.
1823 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1824 if (pNode
!= NULL
) {
1825 mCurrVarStorageNode
= pNode
;
1826 *VarStoreId
= pNode
->mVarStoreId
;
1833 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1834 IN EFI_VARSTORE_ID VarStoreId
,
1835 OUT CHAR8
**DataTypeName
1838 SVfrVarStorageNode
*pNode
;
1840 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1841 return VFR_RETURN_FATAL_ERROR
;
1844 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1845 if (pNode
->mVarStoreId
== VarStoreId
) {
1846 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1847 return VFR_RETURN_SUCCESS
;
1851 return VFR_RETURN_UNDEFINED
;
1854 EFI_VFR_VARSTORE_TYPE
1855 CVfrDataStorage::GetVarStoreType (
1856 IN EFI_VARSTORE_ID VarStoreId
1859 SVfrVarStorageNode
*pNode
;
1860 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1862 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1864 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1865 return VarStoreType
;
1868 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1869 if (pNode
->mVarStoreId
== VarStoreId
) {
1870 VarStoreType
= pNode
->mVarStoreType
;
1871 return VarStoreType
;
1875 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1876 if (pNode
->mVarStoreId
== VarStoreId
) {
1877 VarStoreType
= pNode
->mVarStoreType
;
1878 return VarStoreType
;
1882 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1883 if (pNode
->mVarStoreId
== VarStoreId
) {
1884 VarStoreType
= pNode
->mVarStoreType
;
1885 return VarStoreType
;
1889 return VarStoreType
;
1893 CVfrDataStorage::GetVarStoreGuid (
1894 IN EFI_VARSTORE_ID VarStoreId
1897 SVfrVarStorageNode
*pNode
;
1902 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1906 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1907 if (pNode
->mVarStoreId
== VarStoreId
) {
1908 VarGuid
= &pNode
->mGuid
;
1913 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1914 if (pNode
->mVarStoreId
== VarStoreId
) {
1915 VarGuid
= &pNode
->mGuid
;
1920 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1921 if (pNode
->mVarStoreId
== VarStoreId
) {
1922 VarGuid
= &pNode
->mGuid
;
1931 CVfrDataStorage::GetVarStoreName (
1932 IN EFI_VARSTORE_ID VarStoreId
,
1933 OUT CHAR8
**VarStoreName
1936 SVfrVarStorageNode
*pNode
;
1938 if (VarStoreName
== NULL
) {
1939 return VFR_RETURN_FATAL_ERROR
;
1942 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1943 if (pNode
->mVarStoreId
== VarStoreId
) {
1944 *VarStoreName
= pNode
->mVarStoreName
;
1945 return VFR_RETURN_SUCCESS
;
1949 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1950 if (pNode
->mVarStoreId
== VarStoreId
) {
1951 *VarStoreName
= pNode
->mVarStoreName
;
1952 return VFR_RETURN_SUCCESS
;
1956 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1957 if (pNode
->mVarStoreId
== VarStoreId
) {
1958 *VarStoreName
= pNode
->mVarStoreName
;
1959 return VFR_RETURN_SUCCESS
;
1963 *VarStoreName
= NULL
;
1964 return VFR_RETURN_UNDEFINED
;
1968 CVfrDataStorage::GetEfiVarStoreInfo (
1969 IN OUT EFI_VARSTORE_INFO
*Info
1973 return VFR_RETURN_FATAL_ERROR
;
1976 if (mCurrVarStorageNode
== NULL
) {
1977 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1980 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1981 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1982 switch (Info
->mVarTotalSize
) {
1984 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1987 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1990 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1993 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1996 return VFR_RETURN_FATAL_ERROR
;
1999 return VFR_RETURN_SUCCESS
;
2003 CVfrDataStorage::GetNameVarStoreInfo (
2004 OUT EFI_VARSTORE_INFO
*Info
,
2009 return VFR_RETURN_FATAL_ERROR
;
2012 if (mCurrVarStorageNode
== NULL
) {
2013 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2017 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2019 if (VfrCompatibleMode
) {
2021 return VFR_RETURN_ERROR_ARRARY_NUM
;
2026 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2028 return VFR_RETURN_SUCCESS
;
2031 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2032 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2034 IN EFI_STRING_ID DefaultStoreNameId
,
2038 mObjBinAddr
= ObjBinAddr
;
2040 if (RefName
!= NULL
) {
2041 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2042 strcpy (mRefName
, RefName
);
2048 mDefaultId
= DefaultId
;
2049 mDefaultStoreNameId
= DefaultStoreNameId
;
2052 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2056 if (mRefName
!= NULL
) {
2061 CVfrDefaultStore::CVfrDefaultStore (
2065 mDefaultStoreList
= NULL
;
2068 CVfrDefaultStore::~CVfrDefaultStore (
2072 SVfrDefaultStoreNode
*pTmp
= NULL
;
2074 while (mDefaultStoreList
!= NULL
) {
2075 pTmp
= mDefaultStoreList
;
2076 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2082 CVfrDefaultStore::RegisterDefaultStore (
2083 IN CHAR8
*ObjBinAddr
,
2085 IN EFI_STRING_ID DefaultStoreNameId
,
2089 SVfrDefaultStoreNode
*pNode
= NULL
;
2091 if (RefName
== NULL
) {
2092 return VFR_RETURN_FATAL_ERROR
;
2095 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2096 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2097 return VFR_RETURN_REDEFINED
;
2101 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2102 return VFR_RETURN_OUT_FOR_RESOURCES
;
2105 pNode
->mNext
= mDefaultStoreList
;
2106 mDefaultStoreList
= pNode
;
2108 return VFR_RETURN_SUCCESS
;
2112 * assign new reference name or new default store name id only if
2113 * the original is invalid
2116 CVfrDefaultStore::ReRegisterDefaultStoreById (
2117 IN UINT16 DefaultId
,
2119 IN EFI_STRING_ID DefaultStoreNameId
2122 SVfrDefaultStoreNode
*pNode
= NULL
;
2124 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2125 if (pNode
->mDefaultId
== DefaultId
) {
2130 if (pNode
== NULL
) {
2131 return VFR_RETURN_UNDEFINED
;
2133 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2134 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2135 if (pNode
->mObjBinAddr
!= NULL
) {
2136 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2139 return VFR_RETURN_REDEFINED
;
2142 if (RefName
!= NULL
) {
2143 delete pNode
->mRefName
;
2144 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2145 if (pNode
->mRefName
!= NULL
) {
2146 strcpy (pNode
->mRefName
, RefName
);
2151 return VFR_RETURN_SUCCESS
;
2155 CVfrDefaultStore::DefaultIdRegistered (
2159 SVfrDefaultStoreNode
*pNode
= NULL
;
2161 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2162 if (pNode
->mDefaultId
== DefaultId
) {
2171 CVfrDefaultStore::GetDefaultId (
2173 OUT UINT16
*DefaultId
2176 SVfrDefaultStoreNode
*pTmp
= NULL
;
2178 if (DefaultId
== NULL
) {
2179 return VFR_RETURN_FATAL_ERROR
;
2182 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2183 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2184 *DefaultId
= pTmp
->mDefaultId
;
2185 return VFR_RETURN_SUCCESS
;
2189 return VFR_RETURN_UNDEFINED
;
2193 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2194 IN EFI_VARSTORE_ID DefaultId
,
2195 IN EFI_VARSTORE_INFO
&Info
,
2196 IN CHAR8
*VarStoreName
,
2197 IN EFI_GUID
*VarStoreGuid
,
2199 IN EFI_IFR_TYPE_VALUE Value
2202 SVfrDefaultStoreNode
*pNode
= NULL
;
2203 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2204 INTN Returnvalue
= 0;
2206 if (VarStoreName
== NULL
) {
2207 return VFR_RETURN_FATAL_ERROR
;
2210 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2211 if (pNode
->mDefaultId
== DefaultId
) {
2216 if (pNode
== NULL
) {
2217 return VFR_RETURN_UNDEFINED
;
2220 gCVfrBufferConfig
.Open ();
2222 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2223 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2224 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2229 gCVfrBufferConfig
.Close ();
2231 return VFR_RETURN_SUCCESS
;
2234 gCVfrBufferConfig
.Close ();
2235 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2238 SVfrRuleNode::SVfrRuleNode (
2243 if (RuleName
!= NULL
) {
2244 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2245 strcpy (mRuleName
, RuleName
);
2254 SVfrRuleNode::~SVfrRuleNode (
2258 if (mRuleName
!= NULL
) {
2263 CVfrRulesDB::CVfrRulesDB ()
2266 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2269 CVfrRulesDB::~CVfrRulesDB ()
2271 SVfrRuleNode
*pNode
;
2273 while(mRuleList
!= NULL
) {
2275 mRuleList
= mRuleList
->mNext
;
2281 CVfrRulesDB::RegisterRule (
2287 if (RuleName
== NULL
) {
2291 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2297 pNew
->mNext
= mRuleList
;
2302 CVfrRulesDB::GetRuleId (
2306 SVfrRuleNode
*pNode
;
2308 if (RuleName
== NULL
) {
2309 return EFI_RULE_ID_INVALID
;
2312 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2313 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2314 return pNode
->mRuleId
;
2318 return EFI_RULE_ID_INVALID
;
2321 CVfrRulesDB gCVfrRulesDB
;
2323 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2327 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2328 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2329 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2330 mVarType
= EFI_IFR_TYPE_OTHER
;
2334 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2335 IN EFI_VARSTORE_INFO
&Info
2338 mVarStoreId
= Info
.mVarStoreId
;
2339 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2340 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2341 mVarType
= Info
.mVarType
;
2342 mVarTotalSize
= Info
.mVarTotalSize
;
2346 EFI_VARSTORE_INFO::operator == (
2347 IN EFI_VARSTORE_INFO
*Info
2350 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2351 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2352 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2353 (mVarType
== Info
->mVarType
) &&
2354 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2361 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2364 CVfrQuestionDB::GetFreeQuestionId (
2368 UINT32 Index
, Mask
, Offset
;
2370 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2371 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2376 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2377 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2378 mFreeQIdBitMap
[Index
] |= Mask
;
2379 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2383 return EFI_QUESTION_ID_INVALID
;
2387 CVfrQuestionDB::ChekQuestionIdFree (
2388 IN EFI_QUESTION_ID QId
2391 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2392 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2394 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2398 CVfrQuestionDB::MarkQuestionIdUsed (
2399 IN EFI_QUESTION_ID QId
2402 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2403 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2405 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2409 CVfrQuestionDB::MarkQuestionIdUnused (
2410 IN EFI_QUESTION_ID QId
2413 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2414 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2416 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2419 SVfrQuestionNode::SVfrQuestionNode (
2427 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2430 mQtype
= QUESTION_NORMAL
;
2433 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2434 strcpy (mName
, "$DEFAULT");
2436 mName
= new CHAR8
[strlen (Name
) + 1];
2437 strcpy (mName
, Name
);
2440 if (VarIdStr
!= NULL
) {
2441 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2442 strcpy (mVarIdStr
, VarIdStr
);
2444 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2445 strcpy (mVarIdStr
, "$");
2449 SVfrQuestionNode::~SVfrQuestionNode (
2453 if (mName
!= NULL
) {
2457 if (mVarIdStr
!= NULL
) {
2462 CVfrQuestionDB::CVfrQuestionDB ()
2466 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2467 mFreeQIdBitMap
[Index
] = 0;
2470 // Question ID 0 is reserved.
2471 mFreeQIdBitMap
[0] = 0x80000000;
2472 mQuestionList
= NULL
;
2475 CVfrQuestionDB::~CVfrQuestionDB ()
2477 SVfrQuestionNode
*pNode
;
2479 while (mQuestionList
!= NULL
) {
2480 pNode
= mQuestionList
;
2481 mQuestionList
= mQuestionList
->mNext
;
2487 // Reset to init state
2490 CVfrQuestionDB::ResetInit(
2495 SVfrQuestionNode
*pNode
;
2497 while (mQuestionList
!= NULL
) {
2498 pNode
= mQuestionList
;
2499 mQuestionList
= mQuestionList
->mNext
;
2503 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2504 mFreeQIdBitMap
[Index
] = 0;
2507 // Question ID 0 is reserved.
2508 mFreeQIdBitMap
[0] = 0x80000000;
2509 mQuestionList
= NULL
;
2513 CVfrQuestionDB::PrintAllQuestion (
2517 SVfrQuestionNode
*pNode
= NULL
;
2519 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2520 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2525 CVfrQuestionDB::RegisterQuestion (
2528 IN OUT EFI_QUESTION_ID
&QuestionId
2531 SVfrQuestionNode
*pNode
= NULL
;
2533 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2534 return VFR_RETURN_REDEFINED
;
2537 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2538 return VFR_RETURN_OUT_FOR_RESOURCES
;
2541 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2542 QuestionId
= GetFreeQuestionId ();
2545 // For Framework Vfr, don't check question ID conflict.
2547 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2549 return VFR_RETURN_QUESTIONID_REDEFINED
;
2551 MarkQuestionIdUsed (QuestionId
);
2553 pNode
->mQuestionId
= QuestionId
;
2555 pNode
->mNext
= mQuestionList
;
2556 mQuestionList
= pNode
;
2558 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2560 return VFR_RETURN_SUCCESS
;
2564 CVfrQuestionDB::RegisterOldDateQuestion (
2565 IN CHAR8
*YearVarId
,
2566 IN CHAR8
*MonthVarId
,
2568 IN OUT EFI_QUESTION_ID
&QuestionId
2571 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2574 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2578 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2581 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2584 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2588 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2589 QuestionId
= GetFreeQuestionId ();
2591 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2594 MarkQuestionIdUsed (QuestionId
);
2597 pNode
[0]->mQuestionId
= QuestionId
;
2598 pNode
[1]->mQuestionId
= QuestionId
;
2599 pNode
[2]->mQuestionId
= QuestionId
;
2600 pNode
[0]->mQtype
= QUESTION_DATE
;
2601 pNode
[1]->mQtype
= QUESTION_DATE
;
2602 pNode
[2]->mQtype
= QUESTION_DATE
;
2603 pNode
[0]->mNext
= pNode
[1];
2604 pNode
[1]->mNext
= pNode
[2];
2605 pNode
[2]->mNext
= mQuestionList
;
2606 mQuestionList
= pNode
[0];
2608 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2609 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2610 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2615 for (Index
= 0; Index
< 3; Index
++) {
2616 if (pNode
[Index
] != NULL
) {
2617 delete pNode
[Index
];
2620 QuestionId
= EFI_QUESTION_ID_INVALID
;
2624 CVfrQuestionDB::RegisterNewDateQuestion (
2626 IN CHAR8
*BaseVarId
,
2627 IN OUT EFI_QUESTION_ID
&QuestionId
2630 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2632 CHAR8
*VarIdStr
[3] = {NULL
, };
2635 if (BaseVarId
== NULL
&& Name
== NULL
) {
2636 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2637 QuestionId
= GetFreeQuestionId ();
2639 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2642 MarkQuestionIdUsed (QuestionId
);
2647 if (BaseVarId
!= NULL
) {
2648 Len
= strlen (BaseVarId
);
2650 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2651 if (VarIdStr
[0] != NULL
) {
2652 strcpy (VarIdStr
[0], BaseVarId
);
2653 strcat (VarIdStr
[0], ".Year");
2655 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2656 if (VarIdStr
[1] != NULL
) {
2657 strcpy (VarIdStr
[1], BaseVarId
);
2658 strcat (VarIdStr
[1], ".Month");
2660 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2661 if (VarIdStr
[2] != NULL
) {
2662 strcpy (VarIdStr
[2], BaseVarId
);
2663 strcat (VarIdStr
[2], ".Day");
2666 Len
= strlen (Name
);
2668 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2669 if (VarIdStr
[0] != NULL
) {
2670 strcpy (VarIdStr
[0], Name
);
2671 strcat (VarIdStr
[0], ".Year");
2673 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2674 if (VarIdStr
[1] != NULL
) {
2675 strcpy (VarIdStr
[1], Name
);
2676 strcat (VarIdStr
[1], ".Month");
2678 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2679 if (VarIdStr
[2] != NULL
) {
2680 strcpy (VarIdStr
[2], Name
);
2681 strcat (VarIdStr
[2], ".Day");
2685 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2688 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2691 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2695 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2696 QuestionId
= GetFreeQuestionId ();
2698 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2701 MarkQuestionIdUsed (QuestionId
);
2704 pNode
[0]->mQuestionId
= QuestionId
;
2705 pNode
[1]->mQuestionId
= QuestionId
;
2706 pNode
[2]->mQuestionId
= QuestionId
;
2707 pNode
[0]->mQtype
= QUESTION_DATE
;
2708 pNode
[1]->mQtype
= QUESTION_DATE
;
2709 pNode
[2]->mQtype
= QUESTION_DATE
;
2710 pNode
[0]->mNext
= pNode
[1];
2711 pNode
[1]->mNext
= pNode
[2];
2712 pNode
[2]->mNext
= mQuestionList
;
2713 mQuestionList
= pNode
[0];
2715 for (Index
= 0; Index
< 3; Index
++) {
2716 if (VarIdStr
[Index
] != NULL
) {
2717 delete VarIdStr
[Index
];
2721 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2722 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2723 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2728 for (Index
= 0; Index
< 3; Index
++) {
2729 if (pNode
[Index
] != NULL
) {
2730 delete pNode
[Index
];
2733 if (VarIdStr
[Index
] != NULL
) {
2734 delete VarIdStr
[Index
];
2740 CVfrQuestionDB::RegisterOldTimeQuestion (
2741 IN CHAR8
*HourVarId
,
2742 IN CHAR8
*MinuteVarId
,
2743 IN CHAR8
*SecondVarId
,
2744 IN OUT EFI_QUESTION_ID
&QuestionId
2747 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2750 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2754 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2757 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2760 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2764 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2765 QuestionId
= GetFreeQuestionId ();
2767 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2770 MarkQuestionIdUsed (QuestionId
);
2773 pNode
[0]->mQuestionId
= QuestionId
;
2774 pNode
[1]->mQuestionId
= QuestionId
;
2775 pNode
[2]->mQuestionId
= QuestionId
;
2776 pNode
[0]->mQtype
= QUESTION_TIME
;
2777 pNode
[1]->mQtype
= QUESTION_TIME
;
2778 pNode
[2]->mQtype
= QUESTION_TIME
;
2779 pNode
[0]->mNext
= pNode
[1];
2780 pNode
[1]->mNext
= pNode
[2];
2781 pNode
[2]->mNext
= mQuestionList
;
2782 mQuestionList
= pNode
[0];
2784 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2785 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2786 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2791 for (Index
= 0; Index
< 3; Index
++) {
2792 if (pNode
[Index
] != NULL
) {
2793 delete pNode
[Index
];
2796 QuestionId
= EFI_QUESTION_ID_INVALID
;
2800 CVfrQuestionDB::RegisterNewTimeQuestion (
2802 IN CHAR8
*BaseVarId
,
2803 IN OUT EFI_QUESTION_ID
&QuestionId
2806 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2808 CHAR8
*VarIdStr
[3] = {NULL
, };
2811 if (BaseVarId
== NULL
&& Name
== NULL
) {
2812 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2813 QuestionId
= GetFreeQuestionId ();
2815 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2818 MarkQuestionIdUsed (QuestionId
);
2823 if (BaseVarId
!= NULL
) {
2824 Len
= strlen (BaseVarId
);
2826 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2827 if (VarIdStr
[0] != NULL
) {
2828 strcpy (VarIdStr
[0], BaseVarId
);
2829 strcat (VarIdStr
[0], ".Hour");
2831 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2832 if (VarIdStr
[1] != NULL
) {
2833 strcpy (VarIdStr
[1], BaseVarId
);
2834 strcat (VarIdStr
[1], ".Minute");
2836 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2837 if (VarIdStr
[2] != NULL
) {
2838 strcpy (VarIdStr
[2], BaseVarId
);
2839 strcat (VarIdStr
[2], ".Second");
2842 Len
= strlen (Name
);
2844 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2845 if (VarIdStr
[0] != NULL
) {
2846 strcpy (VarIdStr
[0], Name
);
2847 strcat (VarIdStr
[0], ".Hour");
2849 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2850 if (VarIdStr
[1] != NULL
) {
2851 strcpy (VarIdStr
[1], Name
);
2852 strcat (VarIdStr
[1], ".Minute");
2854 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2855 if (VarIdStr
[2] != NULL
) {
2856 strcpy (VarIdStr
[2], Name
);
2857 strcat (VarIdStr
[2], ".Second");
2861 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2864 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2867 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2871 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2872 QuestionId
= GetFreeQuestionId ();
2874 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2877 MarkQuestionIdUsed (QuestionId
);
2880 pNode
[0]->mQuestionId
= QuestionId
;
2881 pNode
[1]->mQuestionId
= QuestionId
;
2882 pNode
[2]->mQuestionId
= QuestionId
;
2883 pNode
[0]->mQtype
= QUESTION_TIME
;
2884 pNode
[1]->mQtype
= QUESTION_TIME
;
2885 pNode
[2]->mQtype
= QUESTION_TIME
;
2886 pNode
[0]->mNext
= pNode
[1];
2887 pNode
[1]->mNext
= pNode
[2];
2888 pNode
[2]->mNext
= mQuestionList
;
2889 mQuestionList
= pNode
[0];
2891 for (Index
= 0; Index
< 3; Index
++) {
2892 if (VarIdStr
[Index
] != NULL
) {
2893 delete VarIdStr
[Index
];
2897 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2898 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2899 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2904 for (Index
= 0; Index
< 3; Index
++) {
2905 if (pNode
[Index
] != NULL
) {
2906 delete pNode
[Index
];
2909 if (VarIdStr
[Index
] != NULL
) {
2910 delete VarIdStr
[Index
];
2916 CVfrQuestionDB::RegisterRefQuestion (
2918 IN CHAR8
*BaseVarId
,
2919 IN OUT EFI_QUESTION_ID
&QuestionId
2922 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2924 CHAR8
*VarIdStr
[4] = {NULL
, };
2927 if (BaseVarId
== NULL
&& Name
== NULL
) {
2931 if (BaseVarId
!= NULL
) {
2932 Len
= strlen (BaseVarId
);
2934 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2935 if (VarIdStr
[0] != NULL
) {
2936 strcpy (VarIdStr
[0], BaseVarId
);
2937 strcat (VarIdStr
[0], ".QuestionId");
2939 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2940 if (VarIdStr
[1] != NULL
) {
2941 strcpy (VarIdStr
[1], BaseVarId
);
2942 strcat (VarIdStr
[1], ".FormId");
2944 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2945 if (VarIdStr
[2] != NULL
) {
2946 strcpy (VarIdStr
[2], BaseVarId
);
2947 strcat (VarIdStr
[2], ".FormSetGuid");
2949 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2950 if (VarIdStr
[3] != NULL
) {
2951 strcpy (VarIdStr
[3], BaseVarId
);
2952 strcat (VarIdStr
[3], ".DevicePath");
2955 Len
= strlen (Name
);
2957 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2958 if (VarIdStr
[0] != NULL
) {
2959 strcpy (VarIdStr
[0], Name
);
2960 strcat (VarIdStr
[0], ".QuestionId");
2962 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2963 if (VarIdStr
[1] != NULL
) {
2964 strcpy (VarIdStr
[1], Name
);
2965 strcat (VarIdStr
[1], ".FormId");
2967 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2968 if (VarIdStr
[2] != NULL
) {
2969 strcpy (VarIdStr
[2], Name
);
2970 strcat (VarIdStr
[2], ".FormSetGuid");
2972 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2973 if (VarIdStr
[3] != NULL
) {
2974 strcpy (VarIdStr
[3], Name
);
2975 strcat (VarIdStr
[3], ".DevicePath");
2979 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
2982 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
2985 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
2988 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
2992 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2993 QuestionId
= GetFreeQuestionId ();
2995 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2998 MarkQuestionIdUsed (QuestionId
);
3001 pNode
[0]->mQuestionId
= QuestionId
;
3002 pNode
[1]->mQuestionId
= QuestionId
;
3003 pNode
[2]->mQuestionId
= QuestionId
;
3004 pNode
[3]->mQuestionId
= QuestionId
;
3005 pNode
[0]->mQtype
= QUESTION_REF
;
3006 pNode
[1]->mQtype
= QUESTION_REF
;
3007 pNode
[2]->mQtype
= QUESTION_REF
;
3008 pNode
[3]->mQtype
= QUESTION_REF
;
3009 pNode
[0]->mNext
= pNode
[1];
3010 pNode
[1]->mNext
= pNode
[2];
3011 pNode
[2]->mNext
= pNode
[3];
3012 pNode
[3]->mNext
= mQuestionList
;
3013 mQuestionList
= pNode
[0];
3015 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3016 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3017 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3018 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3023 for (Index
= 0; Index
< 4; Index
++) {
3024 if (pNode
[Index
] != NULL
) {
3025 delete pNode
[Index
];
3028 if (VarIdStr
[Index
] != NULL
) {
3029 delete VarIdStr
[Index
];
3035 CVfrQuestionDB::UpdateQuestionId (
3036 IN EFI_QUESTION_ID QId
,
3037 IN EFI_QUESTION_ID NewQId
3040 SVfrQuestionNode
*pNode
= NULL
;
3042 if (QId
== NewQId
) {
3044 return VFR_RETURN_SUCCESS
;
3048 // For Framework Vfr, don't check question ID conflict.
3050 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3051 return VFR_RETURN_REDEFINED
;
3054 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3055 if (pNode
->mQuestionId
== QId
) {
3060 if (pNode
== NULL
) {
3061 return VFR_RETURN_UNDEFINED
;
3064 MarkQuestionIdUnused (QId
);
3065 pNode
->mQuestionId
= NewQId
;
3066 MarkQuestionIdUsed (NewQId
);
3068 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3070 return VFR_RETURN_SUCCESS
;
3074 CVfrQuestionDB::GetQuestionId (
3077 OUT EFI_QUESTION_ID
&QuestionId
,
3078 OUT UINT32
&BitMask
,
3079 OUT EFI_QUESION_TYPE
*QType
3082 SVfrQuestionNode
*pNode
;
3084 QuestionId
= EFI_QUESTION_ID_INVALID
;
3085 BitMask
= 0x00000000;
3086 if (QType
!= NULL
) {
3087 *QType
= QUESTION_NORMAL
;
3090 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3094 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3096 if (strcmp (pNode
->mName
, Name
) != 0) {
3101 if (VarIdStr
!= NULL
) {
3102 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3107 QuestionId
= pNode
->mQuestionId
;
3108 BitMask
= pNode
->mBitMask
;
3109 if (QType
!= NULL
) {
3110 *QType
= pNode
->mQtype
;
3119 CVfrQuestionDB::FindQuestion (
3120 IN EFI_QUESTION_ID QuestionId
3123 SVfrQuestionNode
*pNode
;
3125 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3126 return VFR_RETURN_INVALID_PARAMETER
;
3129 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3130 if (pNode
->mQuestionId
== QuestionId
) {
3131 return VFR_RETURN_SUCCESS
;
3135 return VFR_RETURN_UNDEFINED
;
3139 CVfrQuestionDB::FindQuestion (
3143 SVfrQuestionNode
*pNode
;
3146 return VFR_RETURN_FATAL_ERROR
;
3149 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3150 if (strcmp (pNode
->mName
, Name
) == 0) {
3151 return VFR_RETURN_SUCCESS
;
3155 return VFR_RETURN_UNDEFINED
;
3158 CVfrStringDB::CVfrStringDB ()
3160 mStringFileName
= NULL
;
3163 CVfrStringDB::~CVfrStringDB ()
3165 if (mStringFileName
!= NULL
) {
3166 delete mStringFileName
;
3168 mStringFileName
= NULL
;
3173 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3177 if (StringFileName
== NULL
) {
3181 FileLen
= strlen (StringFileName
) + 1;
3182 mStringFileName
= new CHAR8
[FileLen
];
3183 if (mStringFileName
== NULL
) {
3187 strcpy (mStringFileName
, StringFileName
);
3188 mStringFileName
[FileLen
- 1] = '\0';
3193 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3194 from a set of supported languages.
3196 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3197 contains a set of language codes.
3198 @param[in] Language A variable that contains pointers to Null-terminated
3199 ASCII strings that contain one language codes.
3201 @retval FALSE The best matching language could not be found in SupportedLanguages.
3202 @retval TRUE The best matching language could be found in SupportedLanguages.
3206 CVfrStringDB::GetBestLanguage (
3207 IN CONST CHAR8
*SupportedLanguages
,
3211 UINTN CompareLength
;
3212 UINTN LanguageLength
;
3213 CONST CHAR8
*Supported
;
3215 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3220 // Determine the length of the first RFC 4646 language code in Language
3222 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3225 // Trim back the length of Language used until it is empty
3227 while (LanguageLength
> 0) {
3229 // Loop through all language codes in SupportedLanguages
3231 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3233 // Skip ';' characters in Supported
3235 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3237 // Determine the length of the next language code in Supported
3239 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3241 // If Language is longer than the Supported, then skip to the next language
3243 if (LanguageLength
> CompareLength
) {
3248 // See if the first LanguageLength characters in Supported match Language
3250 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3256 // Trim Language from the right to the next '-' character
3258 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3262 // No matches were found
3269 CVfrStringDB::GetVarStoreNameFormStringId (
3270 IN EFI_STRING_ID StringId
3273 FILE *pInFile
= NULL
;
3278 CHAR16
*UnicodeString
;
3279 CHAR8
*VarStoreName
= NULL
;
3283 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3285 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3287 if (mStringFileName
== '\0' ) {
3291 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3298 fseek (pInFile
, 0, SEEK_END
);
3299 Length
= ftell (pInFile
);
3300 fseek (pInFile
, 0, SEEK_SET
);
3305 StringPtr
= new UINT8
[Length
];
3306 if (StringPtr
== NULL
) {
3310 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3313 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3315 // Check the String package.
3317 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3323 // Search the language, get best language base on RFC 4647 matching algorithm.
3325 Current
= StringPtr
;
3326 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3327 Current
+= PkgHeader
->Header
.Length
;
3328 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3330 // If can't find string package base on language, just return the first string package.
3332 if (Current
- StringPtr
>= Length
) {
3333 Current
= StringPtr
;
3334 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3339 Current
+= PkgHeader
->HdrSize
;
3341 // Find the string block according the stringId.
3343 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3344 if (Status
!= EFI_SUCCESS
) {
3350 // Get varstore name according the string type.
3352 switch (BlockType
) {
3353 case EFI_HII_SIBT_STRING_SCSU
:
3354 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3355 case EFI_HII_SIBT_STRINGS_SCSU
:
3356 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3357 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3358 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3359 strcpy (VarStoreName
, StringName
);
3361 case EFI_HII_SIBT_STRING_UCS2
:
3362 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3363 case EFI_HII_SIBT_STRINGS_UCS2
:
3364 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3365 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3366 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3367 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3368 VarStoreName
= DestTmp
;
3369 while (*UnicodeString
!= '\0') {
3370 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3380 return VarStoreName
;
3384 CVfrStringDB::FindStringBlock (
3385 IN UINT8
*StringData
,
3386 IN EFI_STRING_ID StringId
,
3387 OUT UINT32
*StringTextOffset
,
3388 OUT UINT8
*BlockType
3392 EFI_STRING_ID CurrentStringId
;
3395 UINT8
*StringTextPtr
;
3400 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3404 CurrentStringId
= 1;
3407 // Parse the string blocks to get the string text and font.
3409 BlockHdr
= StringData
;
3412 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3413 switch (*BlockHdr
) {
3414 case EFI_HII_SIBT_STRING_SCSU
:
3415 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3416 StringTextPtr
= BlockHdr
+ Offset
;
3417 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3421 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3422 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3423 StringTextPtr
= BlockHdr
+ Offset
;
3424 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3428 case EFI_HII_SIBT_STRINGS_SCSU
:
3429 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3430 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3431 BlockSize
+= StringTextPtr
- BlockHdr
;
3433 for (Index
= 0; Index
< StringCount
; Index
++) {
3434 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3435 if (CurrentStringId
== StringId
) {
3436 *BlockType
= *BlockHdr
;
3437 *StringTextOffset
= StringTextPtr
- StringData
;
3440 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3445 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3448 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3451 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3452 BlockSize
+= StringTextPtr
- BlockHdr
;
3454 for (Index
= 0; Index
< StringCount
; Index
++) {
3455 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3456 if (CurrentStringId
== StringId
) {
3457 *BlockType
= *BlockHdr
;
3458 *StringTextOffset
= StringTextPtr
- StringData
;
3461 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3466 case EFI_HII_SIBT_STRING_UCS2
:
3467 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3468 StringTextPtr
= BlockHdr
+ Offset
;
3470 // Use StringSize to store the size of the specified string, including the NULL
3473 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3474 BlockSize
+= Offset
+ StringSize
;
3478 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3479 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3480 StringTextPtr
= BlockHdr
+ Offset
;
3482 // Use StrSize to store the size of the specified string, including the NULL
3485 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3486 BlockSize
+= Offset
+ StringSize
;
3490 case EFI_HII_SIBT_STRINGS_UCS2
:
3491 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3492 StringTextPtr
= BlockHdr
+ Offset
;
3493 BlockSize
+= Offset
;
3494 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3495 for (Index
= 0; Index
< StringCount
; Index
++) {
3496 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3497 BlockSize
+= StringSize
;
3498 if (CurrentStringId
== StringId
) {
3499 *BlockType
= *BlockHdr
;
3500 *StringTextOffset
= StringTextPtr
- StringData
;
3503 StringTextPtr
= StringTextPtr
+ StringSize
;
3508 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3509 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3510 StringTextPtr
= BlockHdr
+ Offset
;
3511 BlockSize
+= Offset
;
3514 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3517 for (Index
= 0; Index
< StringCount
; Index
++) {
3518 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3519 BlockSize
+= StringSize
;
3520 if (CurrentStringId
== StringId
) {
3521 *BlockType
= *BlockHdr
;
3522 *StringTextOffset
= StringTextPtr
- StringData
;
3525 StringTextPtr
= StringTextPtr
+ StringSize
;
3530 case EFI_HII_SIBT_DUPLICATE
:
3531 if (CurrentStringId
== StringId
) {
3533 // Incoming StringId is an id of a duplicate string block.
3534 // Update the StringId to be the previous string block.
3535 // Go back to the header of string block to search.
3539 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3540 sizeof (EFI_STRING_ID
)
3542 CurrentStringId
= 1;
3545 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3550 case EFI_HII_SIBT_SKIP1
:
3551 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3552 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3553 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3556 case EFI_HII_SIBT_SKIP2
:
3557 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3558 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3559 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3562 case EFI_HII_SIBT_EXT1
:
3565 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3568 BlockSize
+= Length8
;
3571 case EFI_HII_SIBT_EXT2
:
3572 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3573 BlockSize
+= Ext2
.Length
;
3576 case EFI_HII_SIBT_EXT4
:
3579 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3583 BlockSize
+= Length32
;
3590 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3591 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3592 *BlockType
= *BlockHdr
;
3594 if (StringId
== CurrentStringId
- 1) {
3596 // if only one skip item, return EFI_NOT_FOUND.
3598 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3599 return EFI_NOT_FOUND
;
3605 if (StringId
< CurrentStringId
- 1) {
3606 return EFI_NOT_FOUND
;
3609 BlockHdr
= StringData
+ BlockSize
;
3612 return EFI_NOT_FOUND
;
3616 CVfrStringDB::GetUnicodeStringTextSize (
3623 StringSize
= sizeof (CHAR16
);
3624 StringPtr
= (UINT16
*)StringSrc
;
3625 while (*StringPtr
++ != L
'\0') {
3626 StringSize
+= sizeof (CHAR16
);
3632 BOOLEAN VfrCompatibleMode
= FALSE
;
3634 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;