3 Vfr common library functions.
5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "CommonLib.h"
19 #include "VfrUtilityLib.h"
20 #include "VfrFormPkg.h"
23 CVfrBinaryOutput::WriteLine (
26 IN CONST CHAR8
*LineHeader
,
33 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
37 for (Index
= 0; Index
< BlkSize
; Index
++) {
38 if ((Index
% LineBytes
) == 0) {
39 fprintf (pFile
, "\n%s", LineHeader
);
41 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
46 CVfrBinaryOutput::WriteEnd (
49 IN CONST CHAR8
*LineHeader
,
56 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
60 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
61 if ((Index
% LineBytes
) == 0) {
62 fprintf (pFile
, "\n%s", LineHeader
);
64 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
67 if ((Index
% LineBytes
) == 0) {
68 fprintf (pFile
, "\n%s", LineHeader
);
70 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
73 SConfigInfo::SConfigInfo (
77 IN EFI_IFR_TYPE_VALUE Value
82 mWidth
= (UINT16
)Width
;
83 mValue
= new UINT8
[mWidth
];
89 case EFI_IFR_TYPE_NUM_SIZE_8
:
90 memcpy (mValue
, &Value
.u8
, mWidth
);
92 case EFI_IFR_TYPE_NUM_SIZE_16
:
93 memcpy (mValue
, &Value
.u16
, mWidth
);
95 case EFI_IFR_TYPE_NUM_SIZE_32
:
96 memcpy (mValue
, &Value
.u32
, mWidth
);
98 case EFI_IFR_TYPE_NUM_SIZE_64
:
99 memcpy (mValue
, &Value
.u64
, mWidth
);
101 case EFI_IFR_TYPE_BOOLEAN
:
102 memcpy (mValue
, &Value
.b
, mWidth
);
104 case EFI_IFR_TYPE_TIME
:
105 memcpy (mValue
, &Value
.time
, mWidth
);
107 case EFI_IFR_TYPE_DATE
:
108 memcpy (mValue
, &Value
.date
, mWidth
);
110 case EFI_IFR_TYPE_STRING
:
111 memcpy (mValue
, &Value
.string
, mWidth
);
113 case EFI_IFR_TYPE_BUFFER
:
114 memcpy (mValue
, &Value
.u8
, mWidth
);
117 case EFI_IFR_TYPE_OTHER
:
122 SConfigInfo::~SConfigInfo (
126 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
;
1422 mBufferFieldInfoListHead
= NULL
;
1423 mBufferFieldInfoListTail
= NULL
;
1426 CVfrDataStorage::~CVfrDataStorage (
1430 SVfrVarStorageNode
*pNode
;
1432 while (mBufferVarStoreList
!= NULL
) {
1433 pNode
= mBufferVarStoreList
;
1434 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1437 while (mEfiVarStoreList
!= NULL
) {
1438 pNode
= mEfiVarStoreList
;
1439 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1442 while (mNameVarStoreList
!= NULL
) {
1443 pNode
= mNameVarStoreList
;
1444 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1447 if (mNewVarStorageNode
!= NULL
) {
1448 delete mNewVarStorageNode
;
1453 CVfrDataStorage::GetFreeVarStoreId (
1454 EFI_VFR_VARSTORE_TYPE VarType
1457 UINT32 Index
, Mask
, Offset
;
1460 // Assign the different ID range for the different type VarStore to support Framework Vfr
1463 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1465 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1467 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1471 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1472 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1477 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1478 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1479 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1480 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1484 return EFI_VARSTORE_ID_INVALID
;
1488 CVfrDataStorage::ChekVarStoreIdFree (
1489 IN EFI_VARSTORE_ID VarStoreId
1492 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1493 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1495 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1499 CVfrDataStorage::MarkVarStoreIdUsed (
1500 IN EFI_VARSTORE_ID VarStoreId
1503 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1504 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1506 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1510 CVfrDataStorage::MarkVarStoreIdUnused (
1511 IN EFI_VARSTORE_ID VarStoreId
1514 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1515 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1517 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1521 CVfrDataStorage::DeclareNameVarStoreBegin (
1522 IN CHAR8
*StoreName
,
1523 IN EFI_VARSTORE_ID VarStoreId
1526 SVfrVarStorageNode
*pNode
= NULL
;
1527 EFI_VARSTORE_ID TmpVarStoreId
;
1529 if (StoreName
== NULL
) {
1530 return VFR_RETURN_FATAL_ERROR
;
1533 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1534 return VFR_RETURN_REDEFINED
;
1537 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1538 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1540 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1541 return VFR_RETURN_VARSTOREID_REDEFINED
;
1543 MarkVarStoreIdUsed (VarStoreId
);
1546 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1547 return VFR_RETURN_UNDEFINED
;
1550 mNewVarStorageNode
= pNode
;
1552 return VFR_RETURN_SUCCESS
;
1556 CVfrDataStorage::NameTableAddItem (
1557 IN EFI_STRING_ID Item
1560 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1563 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1564 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1566 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1567 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1568 return VFR_RETURN_OUT_FOR_RESOURCES
;
1570 memcpy (NewTable
, OldTable
, TableSize
);
1571 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1574 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1575 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1577 return VFR_RETURN_SUCCESS
;
1581 CVfrDataStorage::DeclareNameVarStoreEnd (
1585 mNewVarStorageNode
->mGuid
= *Guid
;
1586 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1587 mNameVarStoreList
= mNewVarStorageNode
;
1589 mNewVarStorageNode
= NULL
;
1591 return VFR_RETURN_SUCCESS
;
1595 CVfrDataStorage::DeclareEfiVarStore (
1596 IN CHAR8
*StoreName
,
1598 IN EFI_STRING_ID NameStrId
,
1603 SVfrVarStorageNode
*pNode
;
1604 EFI_VARSTORE_ID VarStoreId
;
1606 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1607 return VFR_RETURN_FATAL_ERROR
;
1610 if (VarSize
> sizeof (UINT64
)) {
1611 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1614 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1615 return VFR_RETURN_REDEFINED
;
1618 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1619 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1620 return VFR_RETURN_OUT_FOR_RESOURCES
;
1623 pNode
->mNext
= mEfiVarStoreList
;
1624 mEfiVarStoreList
= pNode
;
1626 return VFR_RETURN_SUCCESS
;
1630 CVfrDataStorage::DeclareBufferVarStore (
1631 IN CHAR8
*StoreName
,
1633 IN CVfrVarDataTypeDB
*DataTypeDB
,
1635 IN EFI_VARSTORE_ID VarStoreId
,
1639 SVfrVarStorageNode
*pNew
= NULL
;
1640 SVfrDataType
*pDataType
= NULL
;
1641 EFI_VARSTORE_ID TempVarStoreId
;
1643 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1644 return VFR_RETURN_FATAL_ERROR
;
1647 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1648 return VFR_RETURN_REDEFINED
;
1651 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1653 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1654 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1656 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1657 return VFR_RETURN_VARSTOREID_REDEFINED
;
1659 MarkVarStoreIdUsed (VarStoreId
);
1662 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1663 return VFR_RETURN_OUT_FOR_RESOURCES
;
1666 pNew
->mNext
= mBufferVarStoreList
;
1667 mBufferVarStoreList
= pNew
;
1669 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1670 return VFR_RETURN_FATAL_ERROR
;
1673 return VFR_RETURN_SUCCESS
;
1677 CVfrDataStorage::GetVarStoreByDataType (
1678 IN CHAR8
*DataTypeName
,
1679 OUT SVfrVarStorageNode
**VarNode
,
1680 IN EFI_GUID
*VarGuid
1683 SVfrVarStorageNode
*pNode
;
1684 SVfrVarStorageNode
*MatchNode
;
1687 // Framework VFR uses Data type name as varstore name, so don't need check again.
1689 if (VfrCompatibleMode
) {
1690 return VFR_RETURN_UNDEFINED
;
1694 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1695 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1699 if ((VarGuid
!= NULL
)) {
1700 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1702 return VFR_RETURN_SUCCESS
;
1705 if (MatchNode
== NULL
) {
1709 // More than one varstores referred the same data structures.
1711 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1716 if (MatchNode
== NULL
) {
1717 return VFR_RETURN_UNDEFINED
;
1720 *VarNode
= MatchNode
;
1721 return VFR_RETURN_SUCCESS
;
1725 CVfrDataStorage::CheckGuidField (
1726 IN SVfrVarStorageNode
*pNode
,
1727 IN EFI_GUID
*StoreGuid
,
1728 IN BOOLEAN
*HasFoundOne
,
1729 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1732 if (StoreGuid
!= NULL
) {
1734 // If has guid info, compare the guid filed.
1736 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1738 // Both name and guid are same, this this varstore.
1740 mCurrVarStorageNode
= pNode
;
1741 *ReturnCode
= VFR_RETURN_SUCCESS
;
1746 // Not has Guid field, check whether this name is the only one.
1750 // The name has conflict, return name redefined.
1752 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1756 *HasFoundOne
= TRUE
;
1757 mCurrVarStorageNode
= pNode
;
1764 Base on the input store name and guid to find the varstore id.
1766 If both name and guid are inputed, base on the name and guid to
1767 found the varstore. If only name inputed, base on the name to
1768 found the varstore and go on to check whether more than one varstore
1769 has the same name. If only has found one varstore, return this
1770 varstore; if more than one varstore has same name, return varstore
1771 name redefined error. If no varstore found by varstore name, call
1772 function GetVarStoreByDataType and use inputed varstore name as
1773 data type name to search.
1776 CVfrDataStorage::GetVarStoreId (
1777 IN CHAR8
*StoreName
,
1778 OUT EFI_VARSTORE_ID
*VarStoreId
,
1779 IN EFI_GUID
*StoreGuid
1782 EFI_VFR_RETURN_CODE ReturnCode
;
1783 SVfrVarStorageNode
*pNode
;
1784 BOOLEAN HasFoundOne
= FALSE
;
1786 mCurrVarStorageNode
= NULL
;
1788 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1789 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1790 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1791 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1797 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1798 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1799 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1800 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1806 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1807 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1808 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1809 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1816 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1817 return VFR_RETURN_SUCCESS
;
1820 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1823 // Assume that Data strucutre name is used as StoreName, and check again.
1825 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1826 if (pNode
!= NULL
) {
1827 mCurrVarStorageNode
= pNode
;
1828 *VarStoreId
= pNode
->mVarStoreId
;
1835 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1836 IN EFI_VARSTORE_ID VarStoreId
,
1837 OUT CHAR8
**DataTypeName
1840 SVfrVarStorageNode
*pNode
;
1842 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1843 return VFR_RETURN_FATAL_ERROR
;
1846 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1847 if (pNode
->mVarStoreId
== VarStoreId
) {
1848 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1849 return VFR_RETURN_SUCCESS
;
1853 return VFR_RETURN_UNDEFINED
;
1856 EFI_VFR_VARSTORE_TYPE
1857 CVfrDataStorage::GetVarStoreType (
1858 IN EFI_VARSTORE_ID VarStoreId
1861 SVfrVarStorageNode
*pNode
;
1862 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1864 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1866 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1867 return VarStoreType
;
1870 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1871 if (pNode
->mVarStoreId
== VarStoreId
) {
1872 VarStoreType
= pNode
->mVarStoreType
;
1873 return VarStoreType
;
1877 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1878 if (pNode
->mVarStoreId
== VarStoreId
) {
1879 VarStoreType
= pNode
->mVarStoreType
;
1880 return VarStoreType
;
1884 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1885 if (pNode
->mVarStoreId
== VarStoreId
) {
1886 VarStoreType
= pNode
->mVarStoreType
;
1887 return VarStoreType
;
1891 return VarStoreType
;
1895 CVfrDataStorage::GetVarStoreGuid (
1896 IN EFI_VARSTORE_ID VarStoreId
1899 SVfrVarStorageNode
*pNode
;
1904 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1908 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1909 if (pNode
->mVarStoreId
== VarStoreId
) {
1910 VarGuid
= &pNode
->mGuid
;
1915 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1916 if (pNode
->mVarStoreId
== VarStoreId
) {
1917 VarGuid
= &pNode
->mGuid
;
1922 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1923 if (pNode
->mVarStoreId
== VarStoreId
) {
1924 VarGuid
= &pNode
->mGuid
;
1933 CVfrDataStorage::GetVarStoreName (
1934 IN EFI_VARSTORE_ID VarStoreId
,
1935 OUT CHAR8
**VarStoreName
1938 SVfrVarStorageNode
*pNode
;
1940 if (VarStoreName
== NULL
) {
1941 return VFR_RETURN_FATAL_ERROR
;
1944 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1945 if (pNode
->mVarStoreId
== VarStoreId
) {
1946 *VarStoreName
= pNode
->mVarStoreName
;
1947 return VFR_RETURN_SUCCESS
;
1951 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1952 if (pNode
->mVarStoreId
== VarStoreId
) {
1953 *VarStoreName
= pNode
->mVarStoreName
;
1954 return VFR_RETURN_SUCCESS
;
1958 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1959 if (pNode
->mVarStoreId
== VarStoreId
) {
1960 *VarStoreName
= pNode
->mVarStoreName
;
1961 return VFR_RETURN_SUCCESS
;
1965 *VarStoreName
= NULL
;
1966 return VFR_RETURN_UNDEFINED
;
1970 CVfrDataStorage::GetEfiVarStoreInfo (
1971 IN OUT EFI_VARSTORE_INFO
*Info
1975 return VFR_RETURN_FATAL_ERROR
;
1978 if (mCurrVarStorageNode
== NULL
) {
1979 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1982 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1983 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1984 switch (Info
->mVarTotalSize
) {
1986 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1989 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1992 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1995 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1998 return VFR_RETURN_FATAL_ERROR
;
2001 return VFR_RETURN_SUCCESS
;
2005 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2006 IN EFI_VARSTORE_INFO
*Info
2009 BufferVarStoreFieldInfoNode
*pNew
;
2011 if ((pNew
= new BufferVarStoreFieldInfoNode(Info
)) == NULL
) {
2012 return VFR_RETURN_FATAL_ERROR
;
2015 if (mBufferFieldInfoListHead
== NULL
) {
2016 mBufferFieldInfoListHead
= pNew
;
2017 mBufferFieldInfoListTail
= pNew
;
2019 mBufferFieldInfoListTail
->mNext
= pNew
;
2020 mBufferFieldInfoListTail
= pNew
;
2023 return VFR_RETURN_SUCCESS
;
2027 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2028 IN OUT EFI_VARSTORE_INFO
*Info
2031 BufferVarStoreFieldInfoNode
*pNode
;
2033 pNode
= mBufferFieldInfoListHead
;
2034 while (pNode
!= NULL
) {
2035 if (Info
->mVarStoreId
== pNode
->mVarStoreInfo
.mVarStoreId
&&
2036 Info
->mInfo
.mVarOffset
== pNode
->mVarStoreInfo
.mInfo
.mVarOffset
) {
2037 Info
->mVarTotalSize
= pNode
->mVarStoreInfo
.mVarTotalSize
;
2038 Info
->mVarType
= pNode
->mVarStoreInfo
.mVarType
;
2039 return VFR_RETURN_SUCCESS
;
2041 pNode
= pNode
->mNext
;
2043 return VFR_RETURN_FATAL_ERROR
;
2047 CVfrDataStorage::GetNameVarStoreInfo (
2048 OUT EFI_VARSTORE_INFO
*Info
,
2053 return VFR_RETURN_FATAL_ERROR
;
2056 if (mCurrVarStorageNode
== NULL
) {
2057 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2061 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2063 if (VfrCompatibleMode
) {
2065 return VFR_RETURN_ERROR_ARRARY_NUM
;
2070 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2072 return VFR_RETURN_SUCCESS
;
2075 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2076 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2078 IN EFI_STRING_ID DefaultStoreNameId
,
2082 mObjBinAddr
= ObjBinAddr
;
2084 if (RefName
!= NULL
) {
2085 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2086 strcpy (mRefName
, RefName
);
2092 mDefaultId
= DefaultId
;
2093 mDefaultStoreNameId
= DefaultStoreNameId
;
2096 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2100 if (mRefName
!= NULL
) {
2105 CVfrDefaultStore::CVfrDefaultStore (
2109 mDefaultStoreList
= NULL
;
2112 CVfrDefaultStore::~CVfrDefaultStore (
2116 SVfrDefaultStoreNode
*pTmp
= NULL
;
2118 while (mDefaultStoreList
!= NULL
) {
2119 pTmp
= mDefaultStoreList
;
2120 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2126 CVfrDefaultStore::RegisterDefaultStore (
2127 IN CHAR8
*ObjBinAddr
,
2129 IN EFI_STRING_ID DefaultStoreNameId
,
2133 SVfrDefaultStoreNode
*pNode
= NULL
;
2135 if (RefName
== NULL
) {
2136 return VFR_RETURN_FATAL_ERROR
;
2139 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2140 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2141 return VFR_RETURN_REDEFINED
;
2145 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2146 return VFR_RETURN_OUT_FOR_RESOURCES
;
2149 pNode
->mNext
= mDefaultStoreList
;
2150 mDefaultStoreList
= pNode
;
2152 return VFR_RETURN_SUCCESS
;
2156 * assign new reference name or new default store name id only if
2157 * the original is invalid
2160 CVfrDefaultStore::ReRegisterDefaultStoreById (
2161 IN UINT16 DefaultId
,
2163 IN EFI_STRING_ID DefaultStoreNameId
2166 SVfrDefaultStoreNode
*pNode
= NULL
;
2168 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2169 if (pNode
->mDefaultId
== DefaultId
) {
2174 if (pNode
== NULL
) {
2175 return VFR_RETURN_UNDEFINED
;
2177 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2178 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2179 if (pNode
->mObjBinAddr
!= NULL
) {
2180 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2183 return VFR_RETURN_REDEFINED
;
2186 if (RefName
!= NULL
) {
2187 delete pNode
->mRefName
;
2188 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2189 if (pNode
->mRefName
!= NULL
) {
2190 strcpy (pNode
->mRefName
, RefName
);
2195 return VFR_RETURN_SUCCESS
;
2199 CVfrDefaultStore::DefaultIdRegistered (
2203 SVfrDefaultStoreNode
*pNode
= NULL
;
2205 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2206 if (pNode
->mDefaultId
== DefaultId
) {
2215 CVfrDefaultStore::GetDefaultId (
2217 OUT UINT16
*DefaultId
2220 SVfrDefaultStoreNode
*pTmp
= NULL
;
2222 if (DefaultId
== NULL
) {
2223 return VFR_RETURN_FATAL_ERROR
;
2226 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2227 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2228 *DefaultId
= pTmp
->mDefaultId
;
2229 return VFR_RETURN_SUCCESS
;
2233 return VFR_RETURN_UNDEFINED
;
2237 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2238 IN EFI_VARSTORE_ID DefaultId
,
2239 IN EFI_VARSTORE_INFO
&Info
,
2240 IN CHAR8
*VarStoreName
,
2241 IN EFI_GUID
*VarStoreGuid
,
2243 IN EFI_IFR_TYPE_VALUE Value
2246 SVfrDefaultStoreNode
*pNode
= NULL
;
2247 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2248 INTN Returnvalue
= 0;
2250 if (VarStoreName
== NULL
) {
2251 return VFR_RETURN_FATAL_ERROR
;
2254 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2255 if (pNode
->mDefaultId
== DefaultId
) {
2260 if (pNode
== NULL
) {
2261 return VFR_RETURN_UNDEFINED
;
2264 gCVfrBufferConfig
.Open ();
2266 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2267 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2268 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2273 gCVfrBufferConfig
.Close ();
2275 return VFR_RETURN_SUCCESS
;
2278 gCVfrBufferConfig
.Close ();
2279 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2282 SVfrRuleNode::SVfrRuleNode (
2287 if (RuleName
!= NULL
) {
2288 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2289 strcpy (mRuleName
, RuleName
);
2298 SVfrRuleNode::~SVfrRuleNode (
2302 if (mRuleName
!= NULL
) {
2307 CVfrRulesDB::CVfrRulesDB ()
2310 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2313 CVfrRulesDB::~CVfrRulesDB ()
2315 SVfrRuleNode
*pNode
;
2317 while(mRuleList
!= NULL
) {
2319 mRuleList
= mRuleList
->mNext
;
2325 CVfrRulesDB::RegisterRule (
2331 if (RuleName
== NULL
) {
2335 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2341 pNew
->mNext
= mRuleList
;
2346 CVfrRulesDB::GetRuleId (
2350 SVfrRuleNode
*pNode
;
2352 if (RuleName
== NULL
) {
2353 return EFI_RULE_ID_INVALID
;
2356 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2357 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2358 return pNode
->mRuleId
;
2362 return EFI_RULE_ID_INVALID
;
2365 CVfrRulesDB gCVfrRulesDB
;
2367 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2371 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2372 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2373 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2374 mVarType
= EFI_IFR_TYPE_OTHER
;
2378 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2379 IN EFI_VARSTORE_INFO
&Info
2382 mVarStoreId
= Info
.mVarStoreId
;
2383 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2384 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2385 mVarType
= Info
.mVarType
;
2386 mVarTotalSize
= Info
.mVarTotalSize
;
2390 EFI_VARSTORE_INFO::operator == (
2391 IN EFI_VARSTORE_INFO
*Info
2394 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2395 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2396 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2397 (mVarType
== Info
->mVarType
) &&
2398 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2405 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2406 IN EFI_VARSTORE_INFO
*Info
2409 mVarStoreInfo
.mVarType
= Info
->mVarType
;
2410 mVarStoreInfo
.mVarTotalSize
= Info
->mVarTotalSize
;
2411 mVarStoreInfo
.mInfo
.mVarOffset
= Info
->mInfo
.mVarOffset
;
2412 mVarStoreInfo
.mVarStoreId
= Info
->mVarStoreId
;
2416 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2418 mVarStoreInfo
.mVarType
= EFI_IFR_TYPE_OTHER
;
2419 mVarStoreInfo
.mVarTotalSize
= 0;
2420 mVarStoreInfo
.mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2421 mVarStoreInfo
.mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2425 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2428 CVfrQuestionDB::GetFreeQuestionId (
2432 UINT32 Index
, Mask
, Offset
;
2434 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2435 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2440 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2441 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2442 mFreeQIdBitMap
[Index
] |= Mask
;
2443 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2447 return EFI_QUESTION_ID_INVALID
;
2451 CVfrQuestionDB::ChekQuestionIdFree (
2452 IN EFI_QUESTION_ID QId
2455 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2456 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2458 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2462 CVfrQuestionDB::MarkQuestionIdUsed (
2463 IN EFI_QUESTION_ID QId
2466 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2467 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2469 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2473 CVfrQuestionDB::MarkQuestionIdUnused (
2474 IN EFI_QUESTION_ID QId
2477 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2478 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2480 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2483 SVfrQuestionNode::SVfrQuestionNode (
2491 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2494 mQtype
= QUESTION_NORMAL
;
2497 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2498 strcpy (mName
, "$DEFAULT");
2500 mName
= new CHAR8
[strlen (Name
) + 1];
2501 strcpy (mName
, Name
);
2504 if (VarIdStr
!= NULL
) {
2505 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2506 strcpy (mVarIdStr
, VarIdStr
);
2508 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2509 strcpy (mVarIdStr
, "$");
2513 SVfrQuestionNode::~SVfrQuestionNode (
2517 if (mName
!= NULL
) {
2521 if (mVarIdStr
!= NULL
) {
2526 CVfrQuestionDB::CVfrQuestionDB ()
2530 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2531 mFreeQIdBitMap
[Index
] = 0;
2534 // Question ID 0 is reserved.
2535 mFreeQIdBitMap
[0] = 0x80000000;
2536 mQuestionList
= NULL
;
2539 CVfrQuestionDB::~CVfrQuestionDB ()
2541 SVfrQuestionNode
*pNode
;
2543 while (mQuestionList
!= NULL
) {
2544 pNode
= mQuestionList
;
2545 mQuestionList
= mQuestionList
->mNext
;
2551 // Reset to init state
2554 CVfrQuestionDB::ResetInit(
2559 SVfrQuestionNode
*pNode
;
2561 while (mQuestionList
!= NULL
) {
2562 pNode
= mQuestionList
;
2563 mQuestionList
= mQuestionList
->mNext
;
2567 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2568 mFreeQIdBitMap
[Index
] = 0;
2571 // Question ID 0 is reserved.
2572 mFreeQIdBitMap
[0] = 0x80000000;
2573 mQuestionList
= NULL
;
2577 CVfrQuestionDB::PrintAllQuestion (
2581 SVfrQuestionNode
*pNode
= NULL
;
2583 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2584 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2589 CVfrQuestionDB::RegisterQuestion (
2592 IN OUT EFI_QUESTION_ID
&QuestionId
2595 SVfrQuestionNode
*pNode
= NULL
;
2597 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2598 return VFR_RETURN_REDEFINED
;
2601 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2602 return VFR_RETURN_OUT_FOR_RESOURCES
;
2605 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2606 QuestionId
= GetFreeQuestionId ();
2609 // For Framework Vfr, don't check question ID conflict.
2611 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2613 return VFR_RETURN_QUESTIONID_REDEFINED
;
2615 MarkQuestionIdUsed (QuestionId
);
2617 pNode
->mQuestionId
= QuestionId
;
2619 pNode
->mNext
= mQuestionList
;
2620 mQuestionList
= pNode
;
2622 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2624 return VFR_RETURN_SUCCESS
;
2628 CVfrQuestionDB::RegisterOldDateQuestion (
2629 IN CHAR8
*YearVarId
,
2630 IN CHAR8
*MonthVarId
,
2632 IN OUT EFI_QUESTION_ID
&QuestionId
2635 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2638 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2642 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2645 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2648 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2652 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2653 QuestionId
= GetFreeQuestionId ();
2655 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2658 MarkQuestionIdUsed (QuestionId
);
2661 pNode
[0]->mQuestionId
= QuestionId
;
2662 pNode
[1]->mQuestionId
= QuestionId
;
2663 pNode
[2]->mQuestionId
= QuestionId
;
2664 pNode
[0]->mQtype
= QUESTION_DATE
;
2665 pNode
[1]->mQtype
= QUESTION_DATE
;
2666 pNode
[2]->mQtype
= QUESTION_DATE
;
2667 pNode
[0]->mNext
= pNode
[1];
2668 pNode
[1]->mNext
= pNode
[2];
2669 pNode
[2]->mNext
= mQuestionList
;
2670 mQuestionList
= pNode
[0];
2672 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2673 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2674 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2679 for (Index
= 0; Index
< 3; Index
++) {
2680 if (pNode
[Index
] != NULL
) {
2681 delete pNode
[Index
];
2684 QuestionId
= EFI_QUESTION_ID_INVALID
;
2688 CVfrQuestionDB::RegisterNewDateQuestion (
2690 IN CHAR8
*BaseVarId
,
2691 IN OUT EFI_QUESTION_ID
&QuestionId
2694 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2696 CHAR8
*VarIdStr
[3] = {NULL
, };
2699 if (BaseVarId
== NULL
&& Name
== NULL
) {
2700 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2701 QuestionId
= GetFreeQuestionId ();
2703 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2706 MarkQuestionIdUsed (QuestionId
);
2711 if (BaseVarId
!= NULL
) {
2712 Len
= strlen (BaseVarId
);
2714 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2715 if (VarIdStr
[0] != NULL
) {
2716 strcpy (VarIdStr
[0], BaseVarId
);
2717 strcat (VarIdStr
[0], ".Year");
2719 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2720 if (VarIdStr
[1] != NULL
) {
2721 strcpy (VarIdStr
[1], BaseVarId
);
2722 strcat (VarIdStr
[1], ".Month");
2724 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2725 if (VarIdStr
[2] != NULL
) {
2726 strcpy (VarIdStr
[2], BaseVarId
);
2727 strcat (VarIdStr
[2], ".Day");
2730 Len
= strlen (Name
);
2732 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2733 if (VarIdStr
[0] != NULL
) {
2734 strcpy (VarIdStr
[0], Name
);
2735 strcat (VarIdStr
[0], ".Year");
2737 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2738 if (VarIdStr
[1] != NULL
) {
2739 strcpy (VarIdStr
[1], Name
);
2740 strcat (VarIdStr
[1], ".Month");
2742 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2743 if (VarIdStr
[2] != NULL
) {
2744 strcpy (VarIdStr
[2], Name
);
2745 strcat (VarIdStr
[2], ".Day");
2749 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2752 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2755 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2759 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2760 QuestionId
= GetFreeQuestionId ();
2762 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2765 MarkQuestionIdUsed (QuestionId
);
2768 pNode
[0]->mQuestionId
= QuestionId
;
2769 pNode
[1]->mQuestionId
= QuestionId
;
2770 pNode
[2]->mQuestionId
= QuestionId
;
2771 pNode
[0]->mQtype
= QUESTION_DATE
;
2772 pNode
[1]->mQtype
= QUESTION_DATE
;
2773 pNode
[2]->mQtype
= QUESTION_DATE
;
2774 pNode
[0]->mNext
= pNode
[1];
2775 pNode
[1]->mNext
= pNode
[2];
2776 pNode
[2]->mNext
= mQuestionList
;
2777 mQuestionList
= pNode
[0];
2779 for (Index
= 0; Index
< 3; Index
++) {
2780 if (VarIdStr
[Index
] != NULL
) {
2781 delete VarIdStr
[Index
];
2785 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2786 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2787 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2792 for (Index
= 0; Index
< 3; Index
++) {
2793 if (pNode
[Index
] != NULL
) {
2794 delete pNode
[Index
];
2797 if (VarIdStr
[Index
] != NULL
) {
2798 delete VarIdStr
[Index
];
2804 CVfrQuestionDB::RegisterOldTimeQuestion (
2805 IN CHAR8
*HourVarId
,
2806 IN CHAR8
*MinuteVarId
,
2807 IN CHAR8
*SecondVarId
,
2808 IN OUT EFI_QUESTION_ID
&QuestionId
2811 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2814 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2818 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2821 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2824 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2828 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2829 QuestionId
= GetFreeQuestionId ();
2831 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2834 MarkQuestionIdUsed (QuestionId
);
2837 pNode
[0]->mQuestionId
= QuestionId
;
2838 pNode
[1]->mQuestionId
= QuestionId
;
2839 pNode
[2]->mQuestionId
= QuestionId
;
2840 pNode
[0]->mQtype
= QUESTION_TIME
;
2841 pNode
[1]->mQtype
= QUESTION_TIME
;
2842 pNode
[2]->mQtype
= QUESTION_TIME
;
2843 pNode
[0]->mNext
= pNode
[1];
2844 pNode
[1]->mNext
= pNode
[2];
2845 pNode
[2]->mNext
= mQuestionList
;
2846 mQuestionList
= pNode
[0];
2848 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2849 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2850 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2855 for (Index
= 0; Index
< 3; Index
++) {
2856 if (pNode
[Index
] != NULL
) {
2857 delete pNode
[Index
];
2860 QuestionId
= EFI_QUESTION_ID_INVALID
;
2864 CVfrQuestionDB::RegisterNewTimeQuestion (
2866 IN CHAR8
*BaseVarId
,
2867 IN OUT EFI_QUESTION_ID
&QuestionId
2870 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2872 CHAR8
*VarIdStr
[3] = {NULL
, };
2875 if (BaseVarId
== NULL
&& Name
== NULL
) {
2876 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2877 QuestionId
= GetFreeQuestionId ();
2879 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2882 MarkQuestionIdUsed (QuestionId
);
2887 if (BaseVarId
!= NULL
) {
2888 Len
= strlen (BaseVarId
);
2890 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2891 if (VarIdStr
[0] != NULL
) {
2892 strcpy (VarIdStr
[0], BaseVarId
);
2893 strcat (VarIdStr
[0], ".Hour");
2895 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2896 if (VarIdStr
[1] != NULL
) {
2897 strcpy (VarIdStr
[1], BaseVarId
);
2898 strcat (VarIdStr
[1], ".Minute");
2900 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2901 if (VarIdStr
[2] != NULL
) {
2902 strcpy (VarIdStr
[2], BaseVarId
);
2903 strcat (VarIdStr
[2], ".Second");
2906 Len
= strlen (Name
);
2908 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2909 if (VarIdStr
[0] != NULL
) {
2910 strcpy (VarIdStr
[0], Name
);
2911 strcat (VarIdStr
[0], ".Hour");
2913 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2914 if (VarIdStr
[1] != NULL
) {
2915 strcpy (VarIdStr
[1], Name
);
2916 strcat (VarIdStr
[1], ".Minute");
2918 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2919 if (VarIdStr
[2] != NULL
) {
2920 strcpy (VarIdStr
[2], Name
);
2921 strcat (VarIdStr
[2], ".Second");
2925 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2928 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2931 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2935 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2936 QuestionId
= GetFreeQuestionId ();
2938 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2941 MarkQuestionIdUsed (QuestionId
);
2944 pNode
[0]->mQuestionId
= QuestionId
;
2945 pNode
[1]->mQuestionId
= QuestionId
;
2946 pNode
[2]->mQuestionId
= QuestionId
;
2947 pNode
[0]->mQtype
= QUESTION_TIME
;
2948 pNode
[1]->mQtype
= QUESTION_TIME
;
2949 pNode
[2]->mQtype
= QUESTION_TIME
;
2950 pNode
[0]->mNext
= pNode
[1];
2951 pNode
[1]->mNext
= pNode
[2];
2952 pNode
[2]->mNext
= mQuestionList
;
2953 mQuestionList
= pNode
[0];
2955 for (Index
= 0; Index
< 3; Index
++) {
2956 if (VarIdStr
[Index
] != NULL
) {
2957 delete VarIdStr
[Index
];
2961 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2962 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2963 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2968 for (Index
= 0; Index
< 3; Index
++) {
2969 if (pNode
[Index
] != NULL
) {
2970 delete pNode
[Index
];
2973 if (VarIdStr
[Index
] != NULL
) {
2974 delete VarIdStr
[Index
];
2980 CVfrQuestionDB::RegisterRefQuestion (
2982 IN CHAR8
*BaseVarId
,
2983 IN OUT EFI_QUESTION_ID
&QuestionId
2986 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2988 CHAR8
*VarIdStr
[4] = {NULL
, };
2991 if (BaseVarId
== NULL
&& Name
== NULL
) {
2995 if (BaseVarId
!= NULL
) {
2996 Len
= strlen (BaseVarId
);
2998 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2999 if (VarIdStr
[0] != NULL
) {
3000 strcpy (VarIdStr
[0], BaseVarId
);
3001 strcat (VarIdStr
[0], ".QuestionId");
3003 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3004 if (VarIdStr
[1] != NULL
) {
3005 strcpy (VarIdStr
[1], BaseVarId
);
3006 strcat (VarIdStr
[1], ".FormId");
3008 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3009 if (VarIdStr
[2] != NULL
) {
3010 strcpy (VarIdStr
[2], BaseVarId
);
3011 strcat (VarIdStr
[2], ".FormSetGuid");
3013 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3014 if (VarIdStr
[3] != NULL
) {
3015 strcpy (VarIdStr
[3], BaseVarId
);
3016 strcat (VarIdStr
[3], ".DevicePath");
3019 Len
= strlen (Name
);
3021 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
3022 if (VarIdStr
[0] != NULL
) {
3023 strcpy (VarIdStr
[0], Name
);
3024 strcat (VarIdStr
[0], ".QuestionId");
3026 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
3027 if (VarIdStr
[1] != NULL
) {
3028 strcpy (VarIdStr
[1], Name
);
3029 strcat (VarIdStr
[1], ".FormId");
3031 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
3032 if (VarIdStr
[2] != NULL
) {
3033 strcpy (VarIdStr
[2], Name
);
3034 strcat (VarIdStr
[2], ".FormSetGuid");
3036 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
3037 if (VarIdStr
[3] != NULL
) {
3038 strcpy (VarIdStr
[3], Name
);
3039 strcat (VarIdStr
[3], ".DevicePath");
3043 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
3046 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
3049 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
3052 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
3056 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3057 QuestionId
= GetFreeQuestionId ();
3059 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
3062 MarkQuestionIdUsed (QuestionId
);
3065 pNode
[0]->mQuestionId
= QuestionId
;
3066 pNode
[1]->mQuestionId
= QuestionId
;
3067 pNode
[2]->mQuestionId
= QuestionId
;
3068 pNode
[3]->mQuestionId
= QuestionId
;
3069 pNode
[0]->mQtype
= QUESTION_REF
;
3070 pNode
[1]->mQtype
= QUESTION_REF
;
3071 pNode
[2]->mQtype
= QUESTION_REF
;
3072 pNode
[3]->mQtype
= QUESTION_REF
;
3073 pNode
[0]->mNext
= pNode
[1];
3074 pNode
[1]->mNext
= pNode
[2];
3075 pNode
[2]->mNext
= pNode
[3];
3076 pNode
[3]->mNext
= mQuestionList
;
3077 mQuestionList
= pNode
[0];
3079 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3080 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3081 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3082 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3087 for (Index
= 0; Index
< 4; Index
++) {
3088 if (pNode
[Index
] != NULL
) {
3089 delete pNode
[Index
];
3092 if (VarIdStr
[Index
] != NULL
) {
3093 delete VarIdStr
[Index
];
3099 CVfrQuestionDB::UpdateQuestionId (
3100 IN EFI_QUESTION_ID QId
,
3101 IN EFI_QUESTION_ID NewQId
3104 SVfrQuestionNode
*pNode
= NULL
;
3106 if (QId
== NewQId
) {
3108 return VFR_RETURN_SUCCESS
;
3112 // For Framework Vfr, don't check question ID conflict.
3114 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3115 return VFR_RETURN_REDEFINED
;
3118 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3119 if (pNode
->mQuestionId
== QId
) {
3124 if (pNode
== NULL
) {
3125 return VFR_RETURN_UNDEFINED
;
3128 MarkQuestionIdUnused (QId
);
3129 pNode
->mQuestionId
= NewQId
;
3130 MarkQuestionIdUsed (NewQId
);
3132 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3134 return VFR_RETURN_SUCCESS
;
3138 CVfrQuestionDB::GetQuestionId (
3141 OUT EFI_QUESTION_ID
&QuestionId
,
3142 OUT UINT32
&BitMask
,
3143 OUT EFI_QUESION_TYPE
*QType
3146 SVfrQuestionNode
*pNode
;
3148 QuestionId
= EFI_QUESTION_ID_INVALID
;
3149 BitMask
= 0x00000000;
3150 if (QType
!= NULL
) {
3151 *QType
= QUESTION_NORMAL
;
3154 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3158 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3160 if (strcmp (pNode
->mName
, Name
) != 0) {
3165 if (VarIdStr
!= NULL
) {
3166 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3171 QuestionId
= pNode
->mQuestionId
;
3172 BitMask
= pNode
->mBitMask
;
3173 if (QType
!= NULL
) {
3174 *QType
= pNode
->mQtype
;
3183 CVfrQuestionDB::FindQuestion (
3184 IN EFI_QUESTION_ID QuestionId
3187 SVfrQuestionNode
*pNode
;
3189 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3190 return VFR_RETURN_INVALID_PARAMETER
;
3193 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3194 if (pNode
->mQuestionId
== QuestionId
) {
3195 return VFR_RETURN_SUCCESS
;
3199 return VFR_RETURN_UNDEFINED
;
3203 CVfrQuestionDB::FindQuestion (
3207 SVfrQuestionNode
*pNode
;
3210 return VFR_RETURN_FATAL_ERROR
;
3213 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3214 if (strcmp (pNode
->mName
, Name
) == 0) {
3215 return VFR_RETURN_SUCCESS
;
3219 return VFR_RETURN_UNDEFINED
;
3222 CVfrStringDB::CVfrStringDB ()
3224 mStringFileName
= NULL
;
3227 CVfrStringDB::~CVfrStringDB ()
3229 if (mStringFileName
!= NULL
) {
3230 delete mStringFileName
;
3232 mStringFileName
= NULL
;
3237 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3241 if (StringFileName
== NULL
) {
3245 FileLen
= strlen (StringFileName
) + 1;
3246 mStringFileName
= new CHAR8
[FileLen
];
3247 if (mStringFileName
== NULL
) {
3251 strcpy (mStringFileName
, StringFileName
);
3252 mStringFileName
[FileLen
- 1] = '\0';
3257 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3258 from a set of supported languages.
3260 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3261 contains a set of language codes.
3262 @param[in] Language A variable that contains pointers to Null-terminated
3263 ASCII strings that contain one language codes.
3265 @retval FALSE The best matching language could not be found in SupportedLanguages.
3266 @retval TRUE The best matching language could be found in SupportedLanguages.
3270 CVfrStringDB::GetBestLanguage (
3271 IN CONST CHAR8
*SupportedLanguages
,
3275 UINTN CompareLength
;
3276 UINTN LanguageLength
;
3277 CONST CHAR8
*Supported
;
3279 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3284 // Determine the length of the first RFC 4646 language code in Language
3286 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3289 // Trim back the length of Language used until it is empty
3291 while (LanguageLength
> 0) {
3293 // Loop through all language codes in SupportedLanguages
3295 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3297 // Skip ';' characters in Supported
3299 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3301 // Determine the length of the next language code in Supported
3303 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3305 // If Language is longer than the Supported, then skip to the next language
3307 if (LanguageLength
> CompareLength
) {
3312 // See if the first LanguageLength characters in Supported match Language
3314 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3320 // Trim Language from the right to the next '-' character
3322 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3326 // No matches were found
3333 CVfrStringDB::GetVarStoreNameFormStringId (
3334 IN EFI_STRING_ID StringId
3337 FILE *pInFile
= NULL
;
3342 CHAR16
*UnicodeString
;
3343 CHAR8
*VarStoreName
= NULL
;
3347 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3349 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3351 if (mStringFileName
== '\0' ) {
3355 if ((pInFile
= fopen (LongFilePath (mStringFileName
), "rb")) == NULL
) {
3362 fseek (pInFile
, 0, SEEK_END
);
3363 Length
= ftell (pInFile
);
3364 fseek (pInFile
, 0, SEEK_SET
);
3369 StringPtr
= new UINT8
[Length
];
3370 if (StringPtr
== NULL
) {
3374 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3377 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3379 // Check the String package.
3381 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3387 // Search the language, get best language base on RFC 4647 matching algorithm.
3389 Current
= StringPtr
;
3390 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3391 Current
+= PkgHeader
->Header
.Length
;
3392 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3394 // If can't find string package base on language, just return the first string package.
3396 if (Current
- StringPtr
>= Length
) {
3397 Current
= StringPtr
;
3398 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3403 Current
+= PkgHeader
->HdrSize
;
3405 // Find the string block according the stringId.
3407 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3408 if (Status
!= EFI_SUCCESS
) {
3414 // Get varstore name according the string type.
3416 switch (BlockType
) {
3417 case EFI_HII_SIBT_STRING_SCSU
:
3418 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3419 case EFI_HII_SIBT_STRINGS_SCSU
:
3420 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3421 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3422 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3423 strcpy (VarStoreName
, StringName
);
3425 case EFI_HII_SIBT_STRING_UCS2
:
3426 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3427 case EFI_HII_SIBT_STRINGS_UCS2
:
3428 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3429 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3430 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3431 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3432 VarStoreName
= DestTmp
;
3433 while (*UnicodeString
!= '\0') {
3434 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3444 return VarStoreName
;
3448 CVfrStringDB::FindStringBlock (
3449 IN UINT8
*StringData
,
3450 IN EFI_STRING_ID StringId
,
3451 OUT UINT32
*StringTextOffset
,
3452 OUT UINT8
*BlockType
3456 EFI_STRING_ID CurrentStringId
;
3459 UINT8
*StringTextPtr
;
3464 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3468 CurrentStringId
= 1;
3471 // Parse the string blocks to get the string text and font.
3473 BlockHdr
= StringData
;
3476 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3477 switch (*BlockHdr
) {
3478 case EFI_HII_SIBT_STRING_SCSU
:
3479 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3480 StringTextPtr
= BlockHdr
+ Offset
;
3481 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3485 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3486 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3487 StringTextPtr
= BlockHdr
+ Offset
;
3488 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3492 case EFI_HII_SIBT_STRINGS_SCSU
:
3493 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3494 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3495 BlockSize
+= StringTextPtr
- BlockHdr
;
3497 for (Index
= 0; Index
< StringCount
; Index
++) {
3498 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3499 if (CurrentStringId
== StringId
) {
3500 *BlockType
= *BlockHdr
;
3501 *StringTextOffset
= StringTextPtr
- StringData
;
3504 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3509 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3512 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3515 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3516 BlockSize
+= StringTextPtr
- BlockHdr
;
3518 for (Index
= 0; Index
< StringCount
; Index
++) {
3519 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3520 if (CurrentStringId
== StringId
) {
3521 *BlockType
= *BlockHdr
;
3522 *StringTextOffset
= StringTextPtr
- StringData
;
3525 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3530 case EFI_HII_SIBT_STRING_UCS2
:
3531 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3532 StringTextPtr
= BlockHdr
+ Offset
;
3534 // Use StringSize to store the size of the specified string, including the NULL
3537 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3538 BlockSize
+= Offset
+ StringSize
;
3542 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3543 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3544 StringTextPtr
= BlockHdr
+ Offset
;
3546 // Use StrSize to store the size of the specified string, including the NULL
3549 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3550 BlockSize
+= Offset
+ StringSize
;
3554 case EFI_HII_SIBT_STRINGS_UCS2
:
3555 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3556 StringTextPtr
= BlockHdr
+ Offset
;
3557 BlockSize
+= Offset
;
3558 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3559 for (Index
= 0; Index
< StringCount
; Index
++) {
3560 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3561 BlockSize
+= StringSize
;
3562 if (CurrentStringId
== StringId
) {
3563 *BlockType
= *BlockHdr
;
3564 *StringTextOffset
= StringTextPtr
- StringData
;
3567 StringTextPtr
= StringTextPtr
+ StringSize
;
3572 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3573 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3574 StringTextPtr
= BlockHdr
+ Offset
;
3575 BlockSize
+= Offset
;
3578 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3581 for (Index
= 0; Index
< StringCount
; Index
++) {
3582 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3583 BlockSize
+= StringSize
;
3584 if (CurrentStringId
== StringId
) {
3585 *BlockType
= *BlockHdr
;
3586 *StringTextOffset
= StringTextPtr
- StringData
;
3589 StringTextPtr
= StringTextPtr
+ StringSize
;
3594 case EFI_HII_SIBT_DUPLICATE
:
3595 if (CurrentStringId
== StringId
) {
3597 // Incoming StringId is an id of a duplicate string block.
3598 // Update the StringId to be the previous string block.
3599 // Go back to the header of string block to search.
3603 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3604 sizeof (EFI_STRING_ID
)
3606 CurrentStringId
= 1;
3609 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3614 case EFI_HII_SIBT_SKIP1
:
3615 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3616 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3617 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3620 case EFI_HII_SIBT_SKIP2
:
3621 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3622 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3623 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3626 case EFI_HII_SIBT_EXT1
:
3629 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3632 BlockSize
+= Length8
;
3635 case EFI_HII_SIBT_EXT2
:
3636 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3637 BlockSize
+= Ext2
.Length
;
3640 case EFI_HII_SIBT_EXT4
:
3643 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3647 BlockSize
+= Length32
;
3654 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3655 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3656 *BlockType
= *BlockHdr
;
3658 if (StringId
== CurrentStringId
- 1) {
3660 // if only one skip item, return EFI_NOT_FOUND.
3662 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3663 return EFI_NOT_FOUND
;
3669 if (StringId
< CurrentStringId
- 1) {
3670 return EFI_NOT_FOUND
;
3673 BlockHdr
= StringData
+ BlockSize
;
3676 return EFI_NOT_FOUND
;
3680 CVfrStringDB::GetUnicodeStringTextSize (
3687 StringSize
= sizeof (CHAR16
);
3688 StringPtr
= (UINT16
*)StringSrc
;
3689 while (*StringPtr
++ != L
'\0') {
3690 StringSize
+= sizeof (CHAR16
);
3696 BOOLEAN VfrCompatibleMode
= FALSE
;
3698 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;
3699 CVfrDefaultStore gCVfrDefaultStore
;
3700 CVfrDataStorage gCVfrDataStorage
;