3 Vfr common library functions.
5 Copyright (c) 2004 - 2014, 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_OTHER
:
118 SConfigInfo::~SConfigInfo (
122 BUFFER_SAFE_FREE (mValue
);
125 SConfigItem::SConfigItem (
138 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
139 strcpy (mName
, Name
);
144 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
145 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
150 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
156 SConfigItem::SConfigItem (
163 IN EFI_IFR_TYPE_VALUE Value
173 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
174 strcpy (mName
, Name
);
179 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
180 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
185 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
190 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
193 SConfigItem::~SConfigItem (
199 BUFFER_SAFE_FREE (mName
);
200 BUFFER_SAFE_FREE (mGuid
);
201 BUFFER_SAFE_FREE (mId
);
202 while (mInfoStrList
!= NULL
) {
204 mInfoStrList
= mInfoStrList
->mNext
;
206 BUFFER_SAFE_FREE (Info
);
211 CVfrBufferConfig::Register (
219 if (Select (Name
, Guid
) == 0) {
223 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
227 if (mItemListHead
== NULL
) {
228 mItemListHead
= pNew
;
229 mItemListTail
= pNew
;
231 mItemListTail
->mNext
= pNew
;
232 mItemListTail
= pNew
;
240 CVfrBufferConfig::Open (
244 mItemListPos
= mItemListHead
;
248 CVfrBufferConfig::Eof(
252 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
256 CVfrBufferConfig::Select (
264 if (Name
== NULL
|| Guid
== NULL
) {
265 mItemListPos
= mItemListHead
;
268 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
269 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
274 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
277 } else if (p
->mId
!= NULL
) {
290 CVfrBufferConfig::Write (
298 IN EFI_IFR_TYPE_VALUE Value
305 if ((Ret
= Select (Name
, Guid
)) != 0) {
311 if (Select (Name
, Guid
, Id
) != 0) {
312 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
315 if (mItemListHead
== NULL
) {
316 mItemListHead
= pItem
;
317 mItemListTail
= pItem
;
319 mItemListTail
->mNext
= pItem
;
320 mItemListTail
= pItem
;
322 mItemListPos
= pItem
;
324 // tranverse the list to find out if there's already the value for the same offset
325 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
326 if (pInfo
->mOffset
== Offset
) {
330 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
333 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
334 mItemListPos
->mInfoStrList
= pInfo
;
339 if (mItemListHead
== mItemListPos
) {
340 mItemListHead
= mItemListPos
->mNext
;
345 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
348 pItem
->mNext
= mItemListPos
->mNext
;
349 if (mItemListTail
== mItemListPos
) {
350 mItemListTail
= pItem
;
353 mItemListPos
= pItem
->mNext
;
356 case 'i' : // set info
357 if (mItemListPos
->mId
!= NULL
) {
358 delete mItemListPos
->mId
;
360 mItemListPos
->mId
= NULL
;
362 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
365 strcpy (mItemListPos
->mId
, Id
);
378 CVfrBufferConfig::Close (
385 #define BYTES_PRE_LINE 0x10
388 CVfrBufferConfig::OutputCFile (
393 CVfrBinaryOutput Output
;
402 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
403 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
406 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
408 TotalLen
= sizeof (UINT32
);
409 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
410 TotalLen
+= sizeof (UINT16
) * 2;
412 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
414 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
415 fprintf (pFile
, "\n");
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
417 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
419 fprintf (pFile
, "\n};\n");
422 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
423 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
424 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
426 TotalLen
= sizeof (UINT32
);
427 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
428 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
430 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
432 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
433 fprintf (pFile
, "\n");
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
435 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
436 if (Info
->mNext
== NULL
) {
437 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
439 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
442 fprintf (pFile
, "\n};\n");
447 CVfrBufferConfig::CVfrBufferConfig (
451 mItemListHead
= NULL
;
452 mItemListTail
= NULL
;
456 CVfrBufferConfig::~CVfrBufferConfig (
462 while (mItemListHead
!= NULL
) {
464 mItemListHead
= mItemListHead
->mNext
;
468 mItemListHead
= NULL
;
469 mItemListTail
= NULL
;
473 CVfrBufferConfig gCVfrBufferConfig
;
476 CONST CHAR8
*mTypeName
;
480 } gInternalTypesTable
[] = {
481 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
482 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
483 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
484 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
485 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
486 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
487 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
488 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
489 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
490 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
501 if (TypeName
== NULL
) {
505 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
506 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
523 while (*Str
&& *Str
== ' ') {
526 while (*Str
&& *Str
== '0') {
529 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
546 Str
= TrimHex (Str
, &IsHex
);
547 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
549 // BUG: does not handle overflow here
551 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
553 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
554 Value
+= (c
- 'a' + 10);
556 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
557 Value
+= (c
- 'A' + 10);
559 if (c
>= '0' && c
<= '9') {
568 CVfrVarDataTypeDB::RegisterNewType (
572 New
->mNext
= mDataTypeList
;
577 CVfrVarDataTypeDB::ExtractStructTypeName (
583 return VFR_RETURN_FATAL_ERROR
;
586 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
592 if (*VarStr
== '.') {
596 return VFR_RETURN_SUCCESS
;
600 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
607 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
609 ArrayIdx
= INVALID_ARRAY_INDEX
;
612 return VFR_RETURN_FATAL_ERROR
;
615 while((*VarStr
!= '\0') &&
629 return VFR_RETURN_SUCCESS
;
632 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
633 ArrayStr
[Idx
] = *VarStr
;
635 ArrayStr
[Idx
] = '\0';
637 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
638 return VFR_RETURN_DATA_STRING_ERROR
;
640 ArrayIdx
= _STR2U32 (ArrayStr
);
641 if (*VarStr
== ']') {
644 if (*VarStr
== '.') {
647 return VFR_RETURN_SUCCESS
;
649 return VFR_RETURN_DATA_STRING_ERROR
;
652 return VFR_RETURN_SUCCESS
;
656 CVfrVarDataTypeDB::GetTypeField (
657 IN CONST CHAR8
*FName
,
658 IN SVfrDataType
*Type
,
659 OUT SVfrDataField
*&Field
662 SVfrDataField
*pField
= NULL
;
664 if ((FName
== NULL
) && (Type
== NULL
)) {
665 return VFR_RETURN_FATAL_ERROR
;
668 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
670 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
671 // add code to adjust it.
673 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
674 if (strcmp (FName
, "Hour") == 0) {
676 } else if (strcmp (FName
, "Minute") == 0) {
678 } else if (strcmp (FName
, "Second") == 0) {
683 if (strcmp (pField
->mFieldName
, FName
) == 0) {
685 return VFR_RETURN_SUCCESS
;
689 return VFR_RETURN_UNDEFINED
;
693 CVfrVarDataTypeDB::GetFieldOffset (
694 IN SVfrDataField
*Field
,
700 return VFR_RETURN_FATAL_ERROR
;
704 // Framework Vfr file Array Index is from 1.
705 // But Uefi Vfr file Array Index is from 0.
707 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
709 return VFR_RETURN_ERROR_ARRARY_NUM
;
711 ArrayIdx
= ArrayIdx
- 1;
714 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
715 return VFR_RETURN_ERROR_ARRARY_NUM
;
719 // Be compatible with the current usage
720 // If ArraryIdx is not specified, the first one is used.
722 // if ArrayNum is larger than zero, ArraryIdx must be specified.
724 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
725 // return VFR_RETURN_ERROR_ARRARY_NUM;
729 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
730 return VFR_RETURN_SUCCESS
;
734 CVfrVarDataTypeDB::GetFieldWidth (
735 IN SVfrDataField
*Field
742 return Field
->mFieldType
->mType
;
746 CVfrVarDataTypeDB::GetFieldSize (
747 IN SVfrDataField
*Field
,
752 return VFR_RETURN_FATAL_ERROR
;
755 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
756 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
758 return Field
->mFieldType
->mTotalSize
;
763 CVfrVarDataTypeDB::InternalTypesListInit (
767 SVfrDataType
*New
= NULL
;
770 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
771 New
= new SVfrDataType
;
773 strcpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
);
774 New
->mType
= gInternalTypesTable
[Index
].mType
;
775 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
776 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
777 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
778 SVfrDataField
*pYearField
= new SVfrDataField
;
779 SVfrDataField
*pMonthField
= new SVfrDataField
;
780 SVfrDataField
*pDayField
= new SVfrDataField
;
782 strcpy (pYearField
->mFieldName
, "Year");
783 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
784 pYearField
->mOffset
= 0;
785 pYearField
->mNext
= pMonthField
;
786 pYearField
->mArrayNum
= 0;
788 strcpy (pMonthField
->mFieldName
, "Month");
789 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
790 pMonthField
->mOffset
= 2;
791 pMonthField
->mNext
= pDayField
;
792 pMonthField
->mArrayNum
= 0;
794 strcpy (pDayField
->mFieldName
, "Day");
795 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
796 pDayField
->mOffset
= 3;
797 pDayField
->mNext
= NULL
;
798 pDayField
->mArrayNum
= 0;
800 New
->mMembers
= pYearField
;
801 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
802 SVfrDataField
*pHoursField
= new SVfrDataField
;
803 SVfrDataField
*pMinutesField
= new SVfrDataField
;
804 SVfrDataField
*pSecondsField
= new SVfrDataField
;
806 strcpy (pHoursField
->mFieldName
, "Hours");
807 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
808 pHoursField
->mOffset
= 0;
809 pHoursField
->mNext
= pMinutesField
;
810 pHoursField
->mArrayNum
= 0;
812 strcpy (pMinutesField
->mFieldName
, "Minutes");
813 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
814 pMinutesField
->mOffset
= 1;
815 pMinutesField
->mNext
= pSecondsField
;
816 pMinutesField
->mArrayNum
= 0;
818 strcpy (pSecondsField
->mFieldName
, "Seconds");
819 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
820 pSecondsField
->mOffset
= 2;
821 pSecondsField
->mNext
= NULL
;
822 pSecondsField
->mArrayNum
= 0;
824 New
->mMembers
= pHoursField
;
825 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
826 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
827 SVfrDataField
*pFormIdField
= new SVfrDataField
;
828 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
829 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
831 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
832 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
833 pQuestionIdField
->mOffset
= 0;
834 pQuestionIdField
->mNext
= pFormIdField
;
835 pQuestionIdField
->mArrayNum
= 0;
837 strcpy (pFormIdField
->mFieldName
, "FormId");
838 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
839 pFormIdField
->mOffset
= 2;
840 pFormIdField
->mNext
= pFormSetGuidField
;
841 pFormIdField
->mArrayNum
= 0;
843 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
844 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
845 pFormSetGuidField
->mOffset
= 4;
846 pFormSetGuidField
->mNext
= pDevicePathField
;
847 pFormSetGuidField
->mArrayNum
= 0;
849 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
850 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
851 pDevicePathField
->mOffset
= 20;
852 pDevicePathField
->mNext
= NULL
;
853 pDevicePathField
->mArrayNum
= 0;
855 New
->mMembers
= pQuestionIdField
;
857 New
->mMembers
= NULL
;
860 RegisterNewType (New
);
866 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
870 mDataTypeList
= NULL
;
872 mCurrDataField
= NULL
;
873 mPackAlign
= DEFAULT_PACK_ALIGN
;
875 mFirstNewDataTypeName
= NULL
;
877 InternalTypesListInit ();
880 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
885 SVfrDataField
*pField
;
886 SVfrPackStackNode
*pPack
;
888 if (mNewDataType
!= NULL
) {
892 while (mDataTypeList
!= NULL
) {
893 pType
= mDataTypeList
;
894 mDataTypeList
= mDataTypeList
->mNext
;
895 while(pType
->mMembers
!= NULL
) {
896 pField
= pType
->mMembers
;
897 pType
->mMembers
= pType
->mMembers
->mNext
;
903 while (mPackStack
!= NULL
) {
905 mPackStack
= mPackStack
->mNext
;
911 CVfrVarDataTypeDB::Pack (
914 IN CHAR8
*Identifier
,
919 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
921 if (Action
& VFR_PACK_SHOW
) {
922 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
923 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
926 if (Action
& VFR_PACK_PUSH
) {
927 SVfrPackStackNode
*pNew
= NULL
;
929 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
930 return VFR_RETURN_FATAL_ERROR
;
932 pNew
->mNext
= mPackStack
;
936 if (Action
& VFR_PACK_POP
) {
937 SVfrPackStackNode
*pNode
= NULL
;
939 if (mPackStack
== NULL
) {
940 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
943 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
944 if (pNode
->Match (Identifier
) == TRUE
) {
945 mPackAlign
= pNode
->mNumber
;
946 mPackStack
= pNode
->mNext
;
951 if (Action
& VFR_PACK_ASSIGN
) {
952 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
953 if ((PackAlign
== 0) || (PackAlign
> 16)) {
954 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
956 mPackAlign
= PackAlign
;
960 return VFR_RETURN_SUCCESS
;
964 CVfrVarDataTypeDB::DeclareDataTypeBegin (
968 SVfrDataType
*pNewType
= NULL
;
970 pNewType
= new SVfrDataType
;
971 pNewType
->mTypeName
[0] = '\0';
972 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
973 pNewType
->mAlign
= DEFAULT_ALIGN
;
974 pNewType
->mTotalSize
= 0;
975 pNewType
->mMembers
= NULL
;
976 pNewType
->mNext
= NULL
;
978 mNewDataType
= pNewType
;
982 CVfrVarDataTypeDB::SetNewTypeName (
988 if (mNewDataType
== NULL
) {
989 return VFR_RETURN_ERROR_SKIPED
;
991 if (TypeName
== NULL
) {
992 return VFR_RETURN_FATAL_ERROR
;
994 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
995 return VFR_RETURN_INVALID_PARAMETER
;
998 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
999 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
1000 return VFR_RETURN_REDEFINED
;
1004 strcpy(mNewDataType
->mTypeName
, TypeName
);
1005 return VFR_RETURN_SUCCESS
;
1009 CVfrVarDataTypeDB::DataTypeAddField (
1010 IN CHAR8
*FieldName
,
1015 SVfrDataField
*pNewField
= NULL
;
1016 SVfrDataType
*pFieldType
= NULL
;
1017 SVfrDataField
*pTmp
;
1020 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1022 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1023 return VFR_RETURN_INVALID_PARAMETER
;
1026 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1027 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1028 return VFR_RETURN_REDEFINED
;
1032 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1034 if ((pNewField
= new SVfrDataField
) == NULL
) {
1035 return VFR_RETURN_OUT_FOR_RESOURCES
;
1037 strcpy (pNewField
->mFieldName
, FieldName
);
1038 pNewField
->mFieldType
= pFieldType
;
1039 pNewField
->mArrayNum
= ArrayNum
;
1040 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1041 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1043 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1045 if (mNewDataType
->mMembers
== NULL
) {
1046 mNewDataType
->mMembers
= pNewField
;
1047 pNewField
->mNext
= NULL
;
1049 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1051 pTmp
->mNext
= pNewField
;
1052 pNewField
->mNext
= NULL
;
1055 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1056 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1058 return VFR_RETURN_SUCCESS
;
1062 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1066 if (mNewDataType
->mTypeName
[0] == '\0') {
1070 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1071 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1074 RegisterNewType (mNewDataType
);
1075 if (mFirstNewDataTypeName
== NULL
) {
1076 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1079 mNewDataType
= NULL
;
1083 CVfrVarDataTypeDB::GetDataType (
1085 OUT SVfrDataType
**DataType
1088 SVfrDataType
*pDataType
= NULL
;
1090 if (TypeName
== NULL
) {
1091 return VFR_RETURN_ERROR_SKIPED
;
1094 if (DataType
== NULL
) {
1095 return VFR_RETURN_FATAL_ERROR
;
1100 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1101 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1102 *DataType
= pDataType
;
1103 return VFR_RETURN_SUCCESS
;
1107 return VFR_RETURN_UNDEFINED
;
1111 CVfrVarDataTypeDB::GetDataTypeSize (
1116 SVfrDataType
*pDataType
= NULL
;
1119 return VFR_RETURN_FATAL_ERROR
;
1123 DataType
= DataType
& 0x0F;
1126 // For user defined data type, the size can't be got by this function.
1128 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1129 return VFR_RETURN_SUCCESS
;
1132 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1133 if (DataType
== pDataType
->mType
) {
1134 *Size
= pDataType
->mTotalSize
;
1135 return VFR_RETURN_SUCCESS
;
1139 return VFR_RETURN_UNDEFINED
;
1143 CVfrVarDataTypeDB::GetDataTypeSize (
1148 SVfrDataType
*pDataType
= NULL
;
1151 return VFR_RETURN_FATAL_ERROR
;
1156 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1157 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1158 *Size
= pDataType
->mTotalSize
;
1159 return VFR_RETURN_SUCCESS
;
1163 return VFR_RETURN_UNDEFINED
;
1167 CVfrVarDataTypeDB::GetDataFieldInfo (
1174 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1175 UINT32 ArrayIdx
, Tmp
;
1176 SVfrDataType
*pType
= NULL
;
1177 SVfrDataField
*pField
= NULL
;
1180 Type
= EFI_IFR_TYPE_OTHER
;
1183 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1184 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1187 // if it is not struct data type
1189 Type
= pType
->mType
;
1190 Size
= pType
->mTotalSize
;
1192 while (*VarStr
!= '\0') {
1193 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1194 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1195 pType
= pField
->mFieldType
;
1196 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1197 Offset
= (UINT16
) (Offset
+ Tmp
);
1198 Type
= GetFieldWidth (pField
);
1199 Size
= GetFieldSize (pField
, ArrayIdx
);
1201 return VFR_RETURN_SUCCESS
;
1205 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1206 OUT CHAR8
***NameList
,
1207 OUT UINT32
*ListSize
1211 SVfrDataType
*pType
;
1213 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1214 return VFR_RETURN_FATAL_ERROR
;
1220 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1221 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1226 if (*ListSize
== 0) {
1227 return VFR_RETURN_SUCCESS
;
1230 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1232 return VFR_RETURN_OUT_FOR_RESOURCES
;
1235 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1236 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1237 (*NameList
)[Index
] = pType
->mTypeName
;
1240 return VFR_RETURN_SUCCESS
;
1244 CVfrVarDataTypeDB::IsTypeNameDefined (
1248 SVfrDataType
*pType
;
1250 if (TypeName
== NULL
) {
1254 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1255 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1264 CVfrVarDataTypeDB::Dump (
1268 SVfrDataType
*pTNode
;
1269 SVfrDataField
*pFNode
;
1271 fprintf (File
, "\n\n***************************************************************\n");
1272 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1273 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1274 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1275 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1276 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1277 if (pFNode
->mArrayNum
> 0) {
1278 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1279 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1281 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1282 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1285 fprintf (File
, "\t\t};\n");
1286 fprintf (File
, "---------------------------------------------------------------\n");
1288 fprintf (File
, "***************************************************************\n");
1291 #ifdef CVFR_VARDATATYPEDB_DEBUG
1293 CVfrVarDataTypeDB::ParserDB (
1297 SVfrDataType
*pTNode
;
1298 SVfrDataField
*pFNode
;
1300 printf ("***************************************************************\n");
1301 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1302 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1303 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1304 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1305 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1306 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1308 printf ("\t\t};\n");
1309 printf ("---------------------------------------------------------------\n");
1311 printf ("***************************************************************\n");
1315 SVfrVarStorageNode::SVfrVarStorageNode (
1317 IN CHAR8
*StoreName
,
1318 IN EFI_VARSTORE_ID VarStoreId
,
1319 IN EFI_STRING_ID VarName
,
1327 memset (&Guid
, 0, sizeof (EFI_GUID
));
1329 if (StoreName
!= NULL
) {
1330 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1331 strcpy (mVarStoreName
, StoreName
);
1333 mVarStoreName
= NULL
;
1336 mVarStoreId
= VarStoreId
;
1337 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1338 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1339 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1340 mAssignedFlag
= Flag
;
1343 SVfrVarStorageNode::SVfrVarStorageNode (
1345 IN CHAR8
*StoreName
,
1346 IN EFI_VARSTORE_ID VarStoreId
,
1347 IN SVfrDataType
*DataType
,
1354 memset (&Guid
, 0, sizeof (EFI_GUID
));
1356 if (StoreName
!= NULL
) {
1357 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1358 strcpy (mVarStoreName
, StoreName
);
1360 mVarStoreName
= NULL
;
1363 mVarStoreId
= VarStoreId
;
1364 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1365 mStorageInfo
.mDataType
= DataType
;
1366 mAssignedFlag
= Flag
;
1369 SVfrVarStorageNode::SVfrVarStorageNode (
1370 IN CHAR8
*StoreName
,
1371 IN EFI_VARSTORE_ID VarStoreId
1374 if (StoreName
!= NULL
) {
1375 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1376 strcpy (mVarStoreName
, StoreName
);
1378 mVarStoreName
= NULL
;
1381 mVarStoreId
= VarStoreId
;
1382 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1383 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1384 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1387 SVfrVarStorageNode::~SVfrVarStorageNode (
1391 if (mVarStoreName
!= NULL
) {
1392 delete mVarStoreName
;
1395 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1396 delete mStorageInfo
.mNameSpace
.mNameTable
;
1400 CVfrDataStorage::CVfrDataStorage (
1406 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1407 mFreeVarStoreIdBitMap
[Index
] = 0;
1410 // Question ID 0 is reserved.
1411 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1413 mBufferVarStoreList
= NULL
;
1414 mEfiVarStoreList
= NULL
;
1415 mNameVarStoreList
= NULL
;
1416 mCurrVarStorageNode
= NULL
;
1417 mNewVarStorageNode
= NULL
;
1420 CVfrDataStorage::~CVfrDataStorage (
1424 SVfrVarStorageNode
*pNode
;
1426 while (mBufferVarStoreList
!= NULL
) {
1427 pNode
= mBufferVarStoreList
;
1428 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1431 while (mEfiVarStoreList
!= NULL
) {
1432 pNode
= mEfiVarStoreList
;
1433 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1436 while (mNameVarStoreList
!= NULL
) {
1437 pNode
= mNameVarStoreList
;
1438 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1441 if (mNewVarStorageNode
!= NULL
) {
1442 delete mNewVarStorageNode
;
1447 CVfrDataStorage::GetFreeVarStoreId (
1448 EFI_VFR_VARSTORE_TYPE VarType
1451 UINT32 Index
, Mask
, Offset
;
1454 // Assign the different ID range for the different type VarStore to support Framework Vfr
1457 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1459 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1461 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1465 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1466 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1471 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1472 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1473 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1474 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1478 return EFI_VARSTORE_ID_INVALID
;
1482 CVfrDataStorage::ChekVarStoreIdFree (
1483 IN EFI_VARSTORE_ID VarStoreId
1486 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1487 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1489 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1493 CVfrDataStorage::MarkVarStoreIdUsed (
1494 IN EFI_VARSTORE_ID VarStoreId
1497 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1498 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1500 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1504 CVfrDataStorage::MarkVarStoreIdUnused (
1505 IN EFI_VARSTORE_ID VarStoreId
1508 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1509 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1511 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1515 CVfrDataStorage::DeclareNameVarStoreBegin (
1516 IN CHAR8
*StoreName
,
1517 IN EFI_VARSTORE_ID VarStoreId
1520 SVfrVarStorageNode
*pNode
= NULL
;
1521 EFI_VARSTORE_ID TmpVarStoreId
;
1523 if (StoreName
== NULL
) {
1524 return VFR_RETURN_FATAL_ERROR
;
1527 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1528 return VFR_RETURN_REDEFINED
;
1531 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1532 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1534 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1535 return VFR_RETURN_VARSTOREID_REDEFINED
;
1537 MarkVarStoreIdUsed (VarStoreId
);
1540 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1541 return VFR_RETURN_UNDEFINED
;
1544 mNewVarStorageNode
= pNode
;
1546 return VFR_RETURN_SUCCESS
;
1550 CVfrDataStorage::NameTableAddItem (
1551 IN EFI_STRING_ID Item
1554 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1557 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1558 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1560 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1561 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1562 return VFR_RETURN_OUT_FOR_RESOURCES
;
1564 memcpy (NewTable
, OldTable
, TableSize
);
1565 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1568 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1569 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1571 return VFR_RETURN_SUCCESS
;
1575 CVfrDataStorage::DeclareNameVarStoreEnd (
1579 mNewVarStorageNode
->mGuid
= *Guid
;
1580 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1581 mNameVarStoreList
= mNewVarStorageNode
;
1583 mNewVarStorageNode
= NULL
;
1585 return VFR_RETURN_SUCCESS
;
1589 CVfrDataStorage::DeclareEfiVarStore (
1590 IN CHAR8
*StoreName
,
1592 IN EFI_STRING_ID NameStrId
,
1597 SVfrVarStorageNode
*pNode
;
1598 EFI_VARSTORE_ID VarStoreId
;
1600 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1601 return VFR_RETURN_FATAL_ERROR
;
1604 if (VarSize
> sizeof (UINT64
)) {
1605 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1608 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1609 return VFR_RETURN_REDEFINED
;
1612 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1613 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1614 return VFR_RETURN_OUT_FOR_RESOURCES
;
1617 pNode
->mNext
= mEfiVarStoreList
;
1618 mEfiVarStoreList
= pNode
;
1620 return VFR_RETURN_SUCCESS
;
1624 CVfrDataStorage::DeclareBufferVarStore (
1625 IN CHAR8
*StoreName
,
1627 IN CVfrVarDataTypeDB
*DataTypeDB
,
1629 IN EFI_VARSTORE_ID VarStoreId
,
1633 SVfrVarStorageNode
*pNew
= NULL
;
1634 SVfrDataType
*pDataType
= NULL
;
1635 EFI_VARSTORE_ID TempVarStoreId
;
1637 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1638 return VFR_RETURN_FATAL_ERROR
;
1641 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1642 return VFR_RETURN_REDEFINED
;
1645 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1647 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1648 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1650 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1651 return VFR_RETURN_VARSTOREID_REDEFINED
;
1653 MarkVarStoreIdUsed (VarStoreId
);
1656 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1657 return VFR_RETURN_OUT_FOR_RESOURCES
;
1660 pNew
->mNext
= mBufferVarStoreList
;
1661 mBufferVarStoreList
= pNew
;
1663 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1664 return VFR_RETURN_FATAL_ERROR
;
1667 return VFR_RETURN_SUCCESS
;
1671 CVfrDataStorage::GetVarStoreByDataType (
1672 IN CHAR8
*DataTypeName
,
1673 OUT SVfrVarStorageNode
**VarNode
,
1674 IN EFI_GUID
*VarGuid
1677 SVfrVarStorageNode
*pNode
;
1678 SVfrVarStorageNode
*MatchNode
;
1681 // Framework VFR uses Data type name as varstore name, so don't need check again.
1683 if (VfrCompatibleMode
) {
1684 return VFR_RETURN_UNDEFINED
;
1688 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1689 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1693 if ((VarGuid
!= NULL
)) {
1694 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1696 return VFR_RETURN_SUCCESS
;
1699 if (MatchNode
== NULL
) {
1703 // More than one varstores referred the same data structures.
1705 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1710 if (MatchNode
== NULL
) {
1711 return VFR_RETURN_UNDEFINED
;
1714 *VarNode
= MatchNode
;
1715 return VFR_RETURN_SUCCESS
;
1719 CVfrDataStorage::CheckGuidField (
1720 IN SVfrVarStorageNode
*pNode
,
1721 IN EFI_GUID
*StoreGuid
,
1722 IN BOOLEAN
*HasFoundOne
,
1723 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1726 if (StoreGuid
!= NULL
) {
1728 // If has guid info, compare the guid filed.
1730 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1732 // Both name and guid are same, this this varstore.
1734 mCurrVarStorageNode
= pNode
;
1735 *ReturnCode
= VFR_RETURN_SUCCESS
;
1740 // Not has Guid field, check whether this name is the only one.
1744 // The name has conflict, return name redefined.
1746 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1750 *HasFoundOne
= TRUE
;
1751 mCurrVarStorageNode
= pNode
;
1758 Base on the input store name and guid to find the varstore id.
1760 If both name and guid are inputed, base on the name and guid to
1761 found the varstore. If only name inputed, base on the name to
1762 found the varstore and go on to check whether more than one varstore
1763 has the same name. If only has found one varstore, return this
1764 varstore; if more than one varstore has same name, return varstore
1765 name redefined error. If no varstore found by varstore name, call
1766 function GetVarStoreByDataType and use inputed varstore name as
1767 data type name to search.
1770 CVfrDataStorage::GetVarStoreId (
1771 IN CHAR8
*StoreName
,
1772 OUT EFI_VARSTORE_ID
*VarStoreId
,
1773 IN EFI_GUID
*StoreGuid
1776 EFI_VFR_RETURN_CODE ReturnCode
;
1777 SVfrVarStorageNode
*pNode
;
1778 BOOLEAN HasFoundOne
= FALSE
;
1780 mCurrVarStorageNode
= NULL
;
1782 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1783 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1784 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1785 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1791 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1792 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1793 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1794 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1800 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1801 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1802 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1803 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1810 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1811 return VFR_RETURN_SUCCESS
;
1814 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1817 // Assume that Data strucutre name is used as StoreName, and check again.
1819 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1820 if (pNode
!= NULL
) {
1821 mCurrVarStorageNode
= pNode
;
1822 *VarStoreId
= pNode
->mVarStoreId
;
1829 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1830 IN EFI_VARSTORE_ID VarStoreId
,
1831 OUT CHAR8
**DataTypeName
1834 SVfrVarStorageNode
*pNode
;
1836 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1837 return VFR_RETURN_FATAL_ERROR
;
1840 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1841 if (pNode
->mVarStoreId
== VarStoreId
) {
1842 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1843 return VFR_RETURN_SUCCESS
;
1847 return VFR_RETURN_UNDEFINED
;
1850 EFI_VFR_VARSTORE_TYPE
1851 CVfrDataStorage::GetVarStoreType (
1852 IN EFI_VARSTORE_ID VarStoreId
1855 SVfrVarStorageNode
*pNode
;
1856 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1858 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1860 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1861 return VarStoreType
;
1864 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1865 if (pNode
->mVarStoreId
== VarStoreId
) {
1866 VarStoreType
= pNode
->mVarStoreType
;
1867 return VarStoreType
;
1871 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1872 if (pNode
->mVarStoreId
== VarStoreId
) {
1873 VarStoreType
= pNode
->mVarStoreType
;
1874 return VarStoreType
;
1878 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1879 if (pNode
->mVarStoreId
== VarStoreId
) {
1880 VarStoreType
= pNode
->mVarStoreType
;
1881 return VarStoreType
;
1885 return VarStoreType
;
1889 CVfrDataStorage::GetVarStoreGuid (
1890 IN EFI_VARSTORE_ID VarStoreId
1893 SVfrVarStorageNode
*pNode
;
1898 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1902 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1903 if (pNode
->mVarStoreId
== VarStoreId
) {
1904 VarGuid
= &pNode
->mGuid
;
1909 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1910 if (pNode
->mVarStoreId
== VarStoreId
) {
1911 VarGuid
= &pNode
->mGuid
;
1916 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1917 if (pNode
->mVarStoreId
== VarStoreId
) {
1918 VarGuid
= &pNode
->mGuid
;
1927 CVfrDataStorage::GetVarStoreName (
1928 IN EFI_VARSTORE_ID VarStoreId
,
1929 OUT CHAR8
**VarStoreName
1932 SVfrVarStorageNode
*pNode
;
1934 if (VarStoreName
== NULL
) {
1935 return VFR_RETURN_FATAL_ERROR
;
1938 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1939 if (pNode
->mVarStoreId
== VarStoreId
) {
1940 *VarStoreName
= pNode
->mVarStoreName
;
1941 return VFR_RETURN_SUCCESS
;
1945 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1946 if (pNode
->mVarStoreId
== VarStoreId
) {
1947 *VarStoreName
= pNode
->mVarStoreName
;
1948 return VFR_RETURN_SUCCESS
;
1952 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1953 if (pNode
->mVarStoreId
== VarStoreId
) {
1954 *VarStoreName
= pNode
->mVarStoreName
;
1955 return VFR_RETURN_SUCCESS
;
1959 *VarStoreName
= NULL
;
1960 return VFR_RETURN_UNDEFINED
;
1964 CVfrDataStorage::GetEfiVarStoreInfo (
1965 IN OUT EFI_VARSTORE_INFO
*Info
1969 return VFR_RETURN_FATAL_ERROR
;
1972 if (mCurrVarStorageNode
== NULL
) {
1973 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1976 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1977 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1978 switch (Info
->mVarTotalSize
) {
1980 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1983 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1986 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1989 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1992 return VFR_RETURN_FATAL_ERROR
;
1995 return VFR_RETURN_SUCCESS
;
1999 CVfrDataStorage::GetNameVarStoreInfo (
2000 OUT EFI_VARSTORE_INFO
*Info
,
2005 return VFR_RETURN_FATAL_ERROR
;
2008 if (mCurrVarStorageNode
== NULL
) {
2009 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2013 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2015 if (VfrCompatibleMode
) {
2017 return VFR_RETURN_ERROR_ARRARY_NUM
;
2022 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2024 return VFR_RETURN_SUCCESS
;
2027 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2028 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2030 IN EFI_STRING_ID DefaultStoreNameId
,
2034 mObjBinAddr
= ObjBinAddr
;
2036 if (RefName
!= NULL
) {
2037 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2038 strcpy (mRefName
, RefName
);
2044 mDefaultId
= DefaultId
;
2045 mDefaultStoreNameId
= DefaultStoreNameId
;
2048 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2052 if (mRefName
!= NULL
) {
2057 CVfrDefaultStore::CVfrDefaultStore (
2061 mDefaultStoreList
= NULL
;
2064 CVfrDefaultStore::~CVfrDefaultStore (
2068 SVfrDefaultStoreNode
*pTmp
= NULL
;
2070 while (mDefaultStoreList
!= NULL
) {
2071 pTmp
= mDefaultStoreList
;
2072 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2078 CVfrDefaultStore::RegisterDefaultStore (
2079 IN CHAR8
*ObjBinAddr
,
2081 IN EFI_STRING_ID DefaultStoreNameId
,
2085 SVfrDefaultStoreNode
*pNode
= NULL
;
2087 if (RefName
== NULL
) {
2088 return VFR_RETURN_FATAL_ERROR
;
2091 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2092 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2093 return VFR_RETURN_REDEFINED
;
2097 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2098 return VFR_RETURN_OUT_FOR_RESOURCES
;
2101 pNode
->mNext
= mDefaultStoreList
;
2102 mDefaultStoreList
= pNode
;
2104 return VFR_RETURN_SUCCESS
;
2108 * assign new reference name or new default store name id only if
2109 * the original is invalid
2112 CVfrDefaultStore::ReRegisterDefaultStoreById (
2113 IN UINT16 DefaultId
,
2115 IN EFI_STRING_ID DefaultStoreNameId
2118 SVfrDefaultStoreNode
*pNode
= NULL
;
2120 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2121 if (pNode
->mDefaultId
== DefaultId
) {
2126 if (pNode
== NULL
) {
2127 return VFR_RETURN_UNDEFINED
;
2129 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2130 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2131 if (pNode
->mObjBinAddr
!= NULL
) {
2132 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2135 return VFR_RETURN_REDEFINED
;
2138 if (RefName
!= NULL
) {
2139 delete pNode
->mRefName
;
2140 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2141 if (pNode
->mRefName
!= NULL
) {
2142 strcpy (pNode
->mRefName
, RefName
);
2147 return VFR_RETURN_SUCCESS
;
2151 CVfrDefaultStore::DefaultIdRegistered (
2155 SVfrDefaultStoreNode
*pNode
= NULL
;
2157 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2158 if (pNode
->mDefaultId
== DefaultId
) {
2167 CVfrDefaultStore::GetDefaultId (
2169 OUT UINT16
*DefaultId
2172 SVfrDefaultStoreNode
*pTmp
= NULL
;
2174 if (DefaultId
== NULL
) {
2175 return VFR_RETURN_FATAL_ERROR
;
2178 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2179 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2180 *DefaultId
= pTmp
->mDefaultId
;
2181 return VFR_RETURN_SUCCESS
;
2185 return VFR_RETURN_UNDEFINED
;
2189 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2190 IN EFI_VARSTORE_ID DefaultId
,
2191 IN EFI_VARSTORE_INFO
&Info
,
2192 IN CHAR8
*VarStoreName
,
2193 IN EFI_GUID
*VarStoreGuid
,
2195 IN EFI_IFR_TYPE_VALUE Value
2198 SVfrDefaultStoreNode
*pNode
= NULL
;
2199 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2200 INTN Returnvalue
= 0;
2202 if (VarStoreName
== NULL
) {
2203 return VFR_RETURN_FATAL_ERROR
;
2206 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2207 if (pNode
->mDefaultId
== DefaultId
) {
2212 if (pNode
== NULL
) {
2213 return VFR_RETURN_UNDEFINED
;
2216 gCVfrBufferConfig
.Open ();
2218 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2219 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2220 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2225 gCVfrBufferConfig
.Close ();
2227 return VFR_RETURN_SUCCESS
;
2230 gCVfrBufferConfig
.Close ();
2231 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2234 SVfrRuleNode::SVfrRuleNode (
2239 if (RuleName
!= NULL
) {
2240 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2241 strcpy (mRuleName
, RuleName
);
2250 SVfrRuleNode::~SVfrRuleNode (
2254 if (mRuleName
!= NULL
) {
2259 CVfrRulesDB::CVfrRulesDB ()
2262 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2265 CVfrRulesDB::~CVfrRulesDB ()
2267 SVfrRuleNode
*pNode
;
2269 while(mRuleList
!= NULL
) {
2271 mRuleList
= mRuleList
->mNext
;
2277 CVfrRulesDB::RegisterRule (
2283 if (RuleName
== NULL
) {
2287 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2293 pNew
->mNext
= mRuleList
;
2298 CVfrRulesDB::GetRuleId (
2302 SVfrRuleNode
*pNode
;
2304 if (RuleName
== NULL
) {
2305 return EFI_RULE_ID_INVALID
;
2308 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2309 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2310 return pNode
->mRuleId
;
2314 return EFI_RULE_ID_INVALID
;
2317 CVfrRulesDB gCVfrRulesDB
;
2319 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2323 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2324 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2325 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2326 mVarType
= EFI_IFR_TYPE_OTHER
;
2330 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2331 IN EFI_VARSTORE_INFO
&Info
2334 mVarStoreId
= Info
.mVarStoreId
;
2335 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2336 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2337 mVarType
= Info
.mVarType
;
2338 mVarTotalSize
= Info
.mVarTotalSize
;
2342 EFI_VARSTORE_INFO::operator == (
2343 IN EFI_VARSTORE_INFO
*Info
2346 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2347 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2348 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2349 (mVarType
== Info
->mVarType
) &&
2350 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2357 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2360 CVfrQuestionDB::GetFreeQuestionId (
2364 UINT32 Index
, Mask
, Offset
;
2366 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2367 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2372 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2373 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2374 mFreeQIdBitMap
[Index
] |= Mask
;
2375 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2379 return EFI_QUESTION_ID_INVALID
;
2383 CVfrQuestionDB::ChekQuestionIdFree (
2384 IN EFI_QUESTION_ID QId
2387 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2388 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2390 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2394 CVfrQuestionDB::MarkQuestionIdUsed (
2395 IN EFI_QUESTION_ID QId
2398 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2399 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2401 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2405 CVfrQuestionDB::MarkQuestionIdUnused (
2406 IN EFI_QUESTION_ID QId
2409 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2410 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2412 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2415 SVfrQuestionNode::SVfrQuestionNode (
2423 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2426 mQtype
= QUESTION_NORMAL
;
2429 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2430 strcpy (mName
, "$DEFAULT");
2432 mName
= new CHAR8
[strlen (Name
) + 1];
2433 strcpy (mName
, Name
);
2436 if (VarIdStr
!= NULL
) {
2437 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2438 strcpy (mVarIdStr
, VarIdStr
);
2440 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2441 strcpy (mVarIdStr
, "$");
2445 SVfrQuestionNode::~SVfrQuestionNode (
2449 if (mName
!= NULL
) {
2453 if (mVarIdStr
!= NULL
) {
2458 CVfrQuestionDB::CVfrQuestionDB ()
2462 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2463 mFreeQIdBitMap
[Index
] = 0;
2466 // Question ID 0 is reserved.
2467 mFreeQIdBitMap
[0] = 0x80000000;
2468 mQuestionList
= NULL
;
2471 CVfrQuestionDB::~CVfrQuestionDB ()
2473 SVfrQuestionNode
*pNode
;
2475 while (mQuestionList
!= NULL
) {
2476 pNode
= mQuestionList
;
2477 mQuestionList
= mQuestionList
->mNext
;
2483 // Reset to init state
2486 CVfrQuestionDB::ResetInit(
2491 SVfrQuestionNode
*pNode
;
2493 while (mQuestionList
!= NULL
) {
2494 pNode
= mQuestionList
;
2495 mQuestionList
= mQuestionList
->mNext
;
2499 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2500 mFreeQIdBitMap
[Index
] = 0;
2503 // Question ID 0 is reserved.
2504 mFreeQIdBitMap
[0] = 0x80000000;
2505 mQuestionList
= NULL
;
2509 CVfrQuestionDB::PrintAllQuestion (
2513 SVfrQuestionNode
*pNode
= NULL
;
2515 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2516 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2521 CVfrQuestionDB::RegisterQuestion (
2524 IN OUT EFI_QUESTION_ID
&QuestionId
2527 SVfrQuestionNode
*pNode
= NULL
;
2529 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2530 return VFR_RETURN_REDEFINED
;
2533 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2534 return VFR_RETURN_OUT_FOR_RESOURCES
;
2537 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2538 QuestionId
= GetFreeQuestionId ();
2541 // For Framework Vfr, don't check question ID conflict.
2543 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2545 return VFR_RETURN_QUESTIONID_REDEFINED
;
2547 MarkQuestionIdUsed (QuestionId
);
2549 pNode
->mQuestionId
= QuestionId
;
2551 pNode
->mNext
= mQuestionList
;
2552 mQuestionList
= pNode
;
2554 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2556 return VFR_RETURN_SUCCESS
;
2560 CVfrQuestionDB::RegisterOldDateQuestion (
2561 IN CHAR8
*YearVarId
,
2562 IN CHAR8
*MonthVarId
,
2564 IN OUT EFI_QUESTION_ID
&QuestionId
2567 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2570 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2574 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2577 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2580 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2584 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2585 QuestionId
= GetFreeQuestionId ();
2587 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2590 MarkQuestionIdUsed (QuestionId
);
2593 pNode
[0]->mQuestionId
= QuestionId
;
2594 pNode
[1]->mQuestionId
= QuestionId
;
2595 pNode
[2]->mQuestionId
= QuestionId
;
2596 pNode
[0]->mQtype
= QUESTION_DATE
;
2597 pNode
[1]->mQtype
= QUESTION_DATE
;
2598 pNode
[2]->mQtype
= QUESTION_DATE
;
2599 pNode
[0]->mNext
= pNode
[1];
2600 pNode
[1]->mNext
= pNode
[2];
2601 pNode
[2]->mNext
= mQuestionList
;
2602 mQuestionList
= pNode
[0];
2604 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2605 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2606 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2611 for (Index
= 0; Index
< 3; Index
++) {
2612 if (pNode
[Index
] != NULL
) {
2613 delete pNode
[Index
];
2616 QuestionId
= EFI_QUESTION_ID_INVALID
;
2620 CVfrQuestionDB::RegisterNewDateQuestion (
2622 IN CHAR8
*BaseVarId
,
2623 IN OUT EFI_QUESTION_ID
&QuestionId
2626 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2628 CHAR8
*VarIdStr
[3] = {NULL
, };
2631 if (BaseVarId
== NULL
&& Name
== NULL
) {
2632 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2633 QuestionId
= GetFreeQuestionId ();
2635 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2638 MarkQuestionIdUsed (QuestionId
);
2643 if (BaseVarId
!= NULL
) {
2644 Len
= strlen (BaseVarId
);
2646 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2647 if (VarIdStr
[0] != NULL
) {
2648 strcpy (VarIdStr
[0], BaseVarId
);
2649 strcat (VarIdStr
[0], ".Year");
2651 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2652 if (VarIdStr
[1] != NULL
) {
2653 strcpy (VarIdStr
[1], BaseVarId
);
2654 strcat (VarIdStr
[1], ".Month");
2656 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2657 if (VarIdStr
[2] != NULL
) {
2658 strcpy (VarIdStr
[2], BaseVarId
);
2659 strcat (VarIdStr
[2], ".Day");
2662 Len
= strlen (Name
);
2664 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2665 if (VarIdStr
[0] != NULL
) {
2666 strcpy (VarIdStr
[0], Name
);
2667 strcat (VarIdStr
[0], ".Year");
2669 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2670 if (VarIdStr
[1] != NULL
) {
2671 strcpy (VarIdStr
[1], Name
);
2672 strcat (VarIdStr
[1], ".Month");
2674 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2675 if (VarIdStr
[2] != NULL
) {
2676 strcpy (VarIdStr
[2], Name
);
2677 strcat (VarIdStr
[2], ".Day");
2681 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2684 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2687 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2691 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2692 QuestionId
= GetFreeQuestionId ();
2694 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2697 MarkQuestionIdUsed (QuestionId
);
2700 pNode
[0]->mQuestionId
= QuestionId
;
2701 pNode
[1]->mQuestionId
= QuestionId
;
2702 pNode
[2]->mQuestionId
= QuestionId
;
2703 pNode
[0]->mQtype
= QUESTION_DATE
;
2704 pNode
[1]->mQtype
= QUESTION_DATE
;
2705 pNode
[2]->mQtype
= QUESTION_DATE
;
2706 pNode
[0]->mNext
= pNode
[1];
2707 pNode
[1]->mNext
= pNode
[2];
2708 pNode
[2]->mNext
= mQuestionList
;
2709 mQuestionList
= pNode
[0];
2711 for (Index
= 0; Index
< 3; Index
++) {
2712 if (VarIdStr
[Index
] != NULL
) {
2713 delete VarIdStr
[Index
];
2717 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2718 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2719 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2724 for (Index
= 0; Index
< 3; Index
++) {
2725 if (pNode
[Index
] != NULL
) {
2726 delete pNode
[Index
];
2729 if (VarIdStr
[Index
] != NULL
) {
2730 delete VarIdStr
[Index
];
2736 CVfrQuestionDB::RegisterOldTimeQuestion (
2737 IN CHAR8
*HourVarId
,
2738 IN CHAR8
*MinuteVarId
,
2739 IN CHAR8
*SecondVarId
,
2740 IN OUT EFI_QUESTION_ID
&QuestionId
2743 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2746 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2750 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2753 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2756 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2760 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2761 QuestionId
= GetFreeQuestionId ();
2763 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2766 MarkQuestionIdUsed (QuestionId
);
2769 pNode
[0]->mQuestionId
= QuestionId
;
2770 pNode
[1]->mQuestionId
= QuestionId
;
2771 pNode
[2]->mQuestionId
= QuestionId
;
2772 pNode
[0]->mQtype
= QUESTION_TIME
;
2773 pNode
[1]->mQtype
= QUESTION_TIME
;
2774 pNode
[2]->mQtype
= QUESTION_TIME
;
2775 pNode
[0]->mNext
= pNode
[1];
2776 pNode
[1]->mNext
= pNode
[2];
2777 pNode
[2]->mNext
= mQuestionList
;
2778 mQuestionList
= pNode
[0];
2780 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2781 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2782 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2787 for (Index
= 0; Index
< 3; Index
++) {
2788 if (pNode
[Index
] != NULL
) {
2789 delete pNode
[Index
];
2792 QuestionId
= EFI_QUESTION_ID_INVALID
;
2796 CVfrQuestionDB::RegisterNewTimeQuestion (
2798 IN CHAR8
*BaseVarId
,
2799 IN OUT EFI_QUESTION_ID
&QuestionId
2802 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2804 CHAR8
*VarIdStr
[3] = {NULL
, };
2807 if (BaseVarId
== NULL
&& Name
== NULL
) {
2808 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2809 QuestionId
= GetFreeQuestionId ();
2811 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2814 MarkQuestionIdUsed (QuestionId
);
2819 if (BaseVarId
!= NULL
) {
2820 Len
= strlen (BaseVarId
);
2822 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2823 if (VarIdStr
[0] != NULL
) {
2824 strcpy (VarIdStr
[0], BaseVarId
);
2825 strcat (VarIdStr
[0], ".Hour");
2827 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2828 if (VarIdStr
[1] != NULL
) {
2829 strcpy (VarIdStr
[1], BaseVarId
);
2830 strcat (VarIdStr
[1], ".Minute");
2832 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2833 if (VarIdStr
[2] != NULL
) {
2834 strcpy (VarIdStr
[2], BaseVarId
);
2835 strcat (VarIdStr
[2], ".Second");
2838 Len
= strlen (Name
);
2840 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2841 if (VarIdStr
[0] != NULL
) {
2842 strcpy (VarIdStr
[0], Name
);
2843 strcat (VarIdStr
[0], ".Hour");
2845 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2846 if (VarIdStr
[1] != NULL
) {
2847 strcpy (VarIdStr
[1], Name
);
2848 strcat (VarIdStr
[1], ".Minute");
2850 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2851 if (VarIdStr
[2] != NULL
) {
2852 strcpy (VarIdStr
[2], Name
);
2853 strcat (VarIdStr
[2], ".Second");
2857 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2860 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2863 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2867 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2868 QuestionId
= GetFreeQuestionId ();
2870 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2873 MarkQuestionIdUsed (QuestionId
);
2876 pNode
[0]->mQuestionId
= QuestionId
;
2877 pNode
[1]->mQuestionId
= QuestionId
;
2878 pNode
[2]->mQuestionId
= QuestionId
;
2879 pNode
[0]->mQtype
= QUESTION_TIME
;
2880 pNode
[1]->mQtype
= QUESTION_TIME
;
2881 pNode
[2]->mQtype
= QUESTION_TIME
;
2882 pNode
[0]->mNext
= pNode
[1];
2883 pNode
[1]->mNext
= pNode
[2];
2884 pNode
[2]->mNext
= mQuestionList
;
2885 mQuestionList
= pNode
[0];
2887 for (Index
= 0; Index
< 3; Index
++) {
2888 if (VarIdStr
[Index
] != NULL
) {
2889 delete VarIdStr
[Index
];
2893 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2894 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2895 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2900 for (Index
= 0; Index
< 3; Index
++) {
2901 if (pNode
[Index
] != NULL
) {
2902 delete pNode
[Index
];
2905 if (VarIdStr
[Index
] != NULL
) {
2906 delete VarIdStr
[Index
];
2912 CVfrQuestionDB::RegisterRefQuestion (
2914 IN CHAR8
*BaseVarId
,
2915 IN OUT EFI_QUESTION_ID
&QuestionId
2918 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2920 CHAR8
*VarIdStr
[4] = {NULL
, };
2923 if (BaseVarId
== NULL
&& Name
== NULL
) {
2927 if (BaseVarId
!= NULL
) {
2928 Len
= strlen (BaseVarId
);
2930 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2931 if (VarIdStr
[0] != NULL
) {
2932 strcpy (VarIdStr
[0], BaseVarId
);
2933 strcat (VarIdStr
[0], ".QuestionId");
2935 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2936 if (VarIdStr
[1] != NULL
) {
2937 strcpy (VarIdStr
[1], BaseVarId
);
2938 strcat (VarIdStr
[1], ".FormId");
2940 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2941 if (VarIdStr
[2] != NULL
) {
2942 strcpy (VarIdStr
[2], BaseVarId
);
2943 strcat (VarIdStr
[2], ".FormSetGuid");
2945 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2946 if (VarIdStr
[3] != NULL
) {
2947 strcpy (VarIdStr
[3], BaseVarId
);
2948 strcat (VarIdStr
[3], ".DevicePath");
2951 Len
= strlen (Name
);
2953 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2954 if (VarIdStr
[0] != NULL
) {
2955 strcpy (VarIdStr
[0], Name
);
2956 strcat (VarIdStr
[0], ".QuestionId");
2958 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2959 if (VarIdStr
[1] != NULL
) {
2960 strcpy (VarIdStr
[1], Name
);
2961 strcat (VarIdStr
[1], ".FormId");
2963 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2964 if (VarIdStr
[2] != NULL
) {
2965 strcpy (VarIdStr
[2], Name
);
2966 strcat (VarIdStr
[2], ".FormSetGuid");
2968 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2969 if (VarIdStr
[3] != NULL
) {
2970 strcpy (VarIdStr
[3], Name
);
2971 strcat (VarIdStr
[3], ".DevicePath");
2975 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
2978 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
2981 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
2984 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
2988 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2989 QuestionId
= GetFreeQuestionId ();
2991 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2994 MarkQuestionIdUsed (QuestionId
);
2997 pNode
[0]->mQuestionId
= QuestionId
;
2998 pNode
[1]->mQuestionId
= QuestionId
;
2999 pNode
[2]->mQuestionId
= QuestionId
;
3000 pNode
[3]->mQuestionId
= QuestionId
;
3001 pNode
[0]->mQtype
= QUESTION_REF
;
3002 pNode
[1]->mQtype
= QUESTION_REF
;
3003 pNode
[2]->mQtype
= QUESTION_REF
;
3004 pNode
[3]->mQtype
= QUESTION_REF
;
3005 pNode
[0]->mNext
= pNode
[1];
3006 pNode
[1]->mNext
= pNode
[2];
3007 pNode
[2]->mNext
= pNode
[3];
3008 pNode
[3]->mNext
= mQuestionList
;
3009 mQuestionList
= pNode
[0];
3011 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3012 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3013 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3014 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3019 for (Index
= 0; Index
< 4; Index
++) {
3020 if (pNode
[Index
] != NULL
) {
3021 delete pNode
[Index
];
3024 if (VarIdStr
[Index
] != NULL
) {
3025 delete VarIdStr
[Index
];
3031 CVfrQuestionDB::UpdateQuestionId (
3032 IN EFI_QUESTION_ID QId
,
3033 IN EFI_QUESTION_ID NewQId
3036 SVfrQuestionNode
*pNode
= NULL
;
3038 if (QId
== NewQId
) {
3040 return VFR_RETURN_SUCCESS
;
3044 // For Framework Vfr, don't check question ID conflict.
3046 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3047 return VFR_RETURN_REDEFINED
;
3050 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3051 if (pNode
->mQuestionId
== QId
) {
3056 if (pNode
== NULL
) {
3057 return VFR_RETURN_UNDEFINED
;
3060 MarkQuestionIdUnused (QId
);
3061 pNode
->mQuestionId
= NewQId
;
3062 MarkQuestionIdUsed (NewQId
);
3064 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3066 return VFR_RETURN_SUCCESS
;
3070 CVfrQuestionDB::GetQuestionId (
3073 OUT EFI_QUESTION_ID
&QuestionId
,
3074 OUT UINT32
&BitMask
,
3075 OUT EFI_QUESION_TYPE
*QType
3078 SVfrQuestionNode
*pNode
;
3080 QuestionId
= EFI_QUESTION_ID_INVALID
;
3081 BitMask
= 0x00000000;
3082 if (QType
!= NULL
) {
3083 *QType
= QUESTION_NORMAL
;
3086 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3090 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3092 if (strcmp (pNode
->mName
, Name
) != 0) {
3097 if (VarIdStr
!= NULL
) {
3098 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3103 QuestionId
= pNode
->mQuestionId
;
3104 BitMask
= pNode
->mBitMask
;
3105 if (QType
!= NULL
) {
3106 *QType
= pNode
->mQtype
;
3115 CVfrQuestionDB::FindQuestion (
3116 IN EFI_QUESTION_ID QuestionId
3119 SVfrQuestionNode
*pNode
;
3121 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3122 return VFR_RETURN_INVALID_PARAMETER
;
3125 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3126 if (pNode
->mQuestionId
== QuestionId
) {
3127 return VFR_RETURN_SUCCESS
;
3131 return VFR_RETURN_UNDEFINED
;
3135 CVfrQuestionDB::FindQuestion (
3139 SVfrQuestionNode
*pNode
;
3142 return VFR_RETURN_FATAL_ERROR
;
3145 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3146 if (strcmp (pNode
->mName
, Name
) == 0) {
3147 return VFR_RETURN_SUCCESS
;
3151 return VFR_RETURN_UNDEFINED
;
3154 CVfrStringDB::CVfrStringDB ()
3156 mStringFileName
= NULL
;
3159 CVfrStringDB::~CVfrStringDB ()
3161 if (mStringFileName
!= NULL
) {
3162 delete mStringFileName
;
3164 mStringFileName
= NULL
;
3169 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3173 if (StringFileName
== NULL
) {
3177 FileLen
= strlen (StringFileName
) + 1;
3178 mStringFileName
= new CHAR8
[FileLen
];
3179 if (mStringFileName
== NULL
) {
3183 strcpy (mStringFileName
, StringFileName
);
3184 mStringFileName
[FileLen
- 1] = '\0';
3189 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3190 from a set of supported languages.
3192 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3193 contains a set of language codes.
3194 @param[in] Language A variable that contains pointers to Null-terminated
3195 ASCII strings that contain one language codes.
3197 @retval FALSE The best matching language could not be found in SupportedLanguages.
3198 @retval TRUE The best matching language could be found in SupportedLanguages.
3202 CVfrStringDB::GetBestLanguage (
3203 IN CONST CHAR8
*SupportedLanguages
,
3207 UINTN CompareLength
;
3208 UINTN LanguageLength
;
3209 CONST CHAR8
*Supported
;
3211 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3216 // Determine the length of the first RFC 4646 language code in Language
3218 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3221 // Trim back the length of Language used until it is empty
3223 while (LanguageLength
> 0) {
3225 // Loop through all language codes in SupportedLanguages
3227 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3229 // Skip ';' characters in Supported
3231 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3233 // Determine the length of the next language code in Supported
3235 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3237 // If Language is longer than the Supported, then skip to the next language
3239 if (LanguageLength
> CompareLength
) {
3244 // See if the first LanguageLength characters in Supported match Language
3246 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3252 // Trim Language from the right to the next '-' character
3254 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3258 // No matches were found
3265 CVfrStringDB::GetVarStoreNameFormStringId (
3266 IN EFI_STRING_ID StringId
3269 FILE *pInFile
= NULL
;
3274 CHAR16
*UnicodeString
;
3275 CHAR8
*VarStoreName
= NULL
;
3279 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3281 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3283 if (mStringFileName
== '\0' ) {
3287 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3294 fseek (pInFile
, 0, SEEK_END
);
3295 Length
= ftell (pInFile
);
3296 fseek (pInFile
, 0, SEEK_SET
);
3301 StringPtr
= new UINT8
[Length
];
3302 if (StringPtr
== NULL
) {
3306 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3309 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3311 // Check the String package.
3313 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3319 // Search the language, get best language base on RFC 4647 matching algorithm.
3321 Current
= StringPtr
;
3322 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3323 Current
+= PkgHeader
->Header
.Length
;
3324 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3326 // If can't find string package base on language, just return the first string package.
3328 if (Current
- StringPtr
>= Length
) {
3329 Current
= StringPtr
;
3330 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3335 Current
+= PkgHeader
->HdrSize
;
3337 // Find the string block according the stringId.
3339 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3340 if (Status
!= EFI_SUCCESS
) {
3346 // Get varstore name according the string type.
3348 switch (BlockType
) {
3349 case EFI_HII_SIBT_STRING_SCSU
:
3350 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3351 case EFI_HII_SIBT_STRINGS_SCSU
:
3352 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3353 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3354 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3355 strcpy (VarStoreName
, StringName
);
3357 case EFI_HII_SIBT_STRING_UCS2
:
3358 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3359 case EFI_HII_SIBT_STRINGS_UCS2
:
3360 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3361 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3362 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3363 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3364 VarStoreName
= DestTmp
;
3365 while (*UnicodeString
!= '\0') {
3366 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3376 return VarStoreName
;
3380 CVfrStringDB::FindStringBlock (
3381 IN UINT8
*StringData
,
3382 IN EFI_STRING_ID StringId
,
3383 OUT UINT32
*StringTextOffset
,
3384 OUT UINT8
*BlockType
3388 EFI_STRING_ID CurrentStringId
;
3391 UINT8
*StringTextPtr
;
3396 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3400 CurrentStringId
= 1;
3403 // Parse the string blocks to get the string text and font.
3405 BlockHdr
= StringData
;
3408 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3409 switch (*BlockHdr
) {
3410 case EFI_HII_SIBT_STRING_SCSU
:
3411 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3412 StringTextPtr
= BlockHdr
+ Offset
;
3413 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3417 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3418 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3419 StringTextPtr
= BlockHdr
+ Offset
;
3420 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3424 case EFI_HII_SIBT_STRINGS_SCSU
:
3425 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3426 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3427 BlockSize
+= StringTextPtr
- BlockHdr
;
3429 for (Index
= 0; Index
< StringCount
; Index
++) {
3430 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3431 if (CurrentStringId
== StringId
) {
3432 *BlockType
= *BlockHdr
;
3433 *StringTextOffset
= StringTextPtr
- StringData
;
3436 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3441 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3444 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3447 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3448 BlockSize
+= StringTextPtr
- BlockHdr
;
3450 for (Index
= 0; Index
< StringCount
; Index
++) {
3451 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3452 if (CurrentStringId
== StringId
) {
3453 *BlockType
= *BlockHdr
;
3454 *StringTextOffset
= StringTextPtr
- StringData
;
3457 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3462 case EFI_HII_SIBT_STRING_UCS2
:
3463 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3464 StringTextPtr
= BlockHdr
+ Offset
;
3466 // Use StringSize to store the size of the specified string, including the NULL
3469 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3470 BlockSize
+= Offset
+ StringSize
;
3474 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3475 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3476 StringTextPtr
= BlockHdr
+ Offset
;
3478 // Use StrSize to store the size of the specified string, including the NULL
3481 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3482 BlockSize
+= Offset
+ StringSize
;
3486 case EFI_HII_SIBT_STRINGS_UCS2
:
3487 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3488 StringTextPtr
= BlockHdr
+ Offset
;
3489 BlockSize
+= Offset
;
3490 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3491 for (Index
= 0; Index
< StringCount
; Index
++) {
3492 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3493 BlockSize
+= StringSize
;
3494 if (CurrentStringId
== StringId
) {
3495 *BlockType
= *BlockHdr
;
3496 *StringTextOffset
= StringTextPtr
- StringData
;
3499 StringTextPtr
= StringTextPtr
+ StringSize
;
3504 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3505 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3506 StringTextPtr
= BlockHdr
+ Offset
;
3507 BlockSize
+= Offset
;
3510 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3513 for (Index
= 0; Index
< StringCount
; Index
++) {
3514 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3515 BlockSize
+= StringSize
;
3516 if (CurrentStringId
== StringId
) {
3517 *BlockType
= *BlockHdr
;
3518 *StringTextOffset
= StringTextPtr
- StringData
;
3521 StringTextPtr
= StringTextPtr
+ StringSize
;
3526 case EFI_HII_SIBT_DUPLICATE
:
3527 if (CurrentStringId
== StringId
) {
3529 // Incoming StringId is an id of a duplicate string block.
3530 // Update the StringId to be the previous string block.
3531 // Go back to the header of string block to search.
3535 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3536 sizeof (EFI_STRING_ID
)
3538 CurrentStringId
= 1;
3541 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3546 case EFI_HII_SIBT_SKIP1
:
3547 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3548 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3549 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3552 case EFI_HII_SIBT_SKIP2
:
3553 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3554 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3555 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3558 case EFI_HII_SIBT_EXT1
:
3561 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3564 BlockSize
+= Length8
;
3567 case EFI_HII_SIBT_EXT2
:
3568 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3569 BlockSize
+= Ext2
.Length
;
3572 case EFI_HII_SIBT_EXT4
:
3575 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3579 BlockSize
+= Length32
;
3586 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3587 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3588 *BlockType
= *BlockHdr
;
3590 if (StringId
== CurrentStringId
- 1) {
3592 // if only one skip item, return EFI_NOT_FOUND.
3594 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3595 return EFI_NOT_FOUND
;
3601 if (StringId
< CurrentStringId
- 1) {
3602 return EFI_NOT_FOUND
;
3605 BlockHdr
= StringData
+ BlockSize
;
3608 return EFI_NOT_FOUND
;
3612 CVfrStringDB::GetUnicodeStringTextSize (
3619 StringSize
= sizeof (CHAR16
);
3620 StringPtr
= (UINT16
*)StringSrc
;
3621 while (*StringPtr
++ != L
'\0') {
3622 StringSize
+= sizeof (CHAR16
);
3628 BOOLEAN VfrCompatibleMode
= FALSE
;
3630 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;