3 Vfr common library functions.
5 Copyright (c) 2004 - 2013, 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 "VfrUtilityLib.h"
19 #include "VfrFormPkg.h"
22 CVfrBinaryOutput::WriteLine (
25 IN CONST CHAR8
*LineHeader
,
32 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
36 for (Index
= 0; Index
< BlkSize
; Index
++) {
37 if ((Index
% LineBytes
) == 0) {
38 fprintf (pFile
, "\n%s", LineHeader
);
40 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
45 CVfrBinaryOutput::WriteEnd (
48 IN CONST CHAR8
*LineHeader
,
55 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
59 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
60 if ((Index
% LineBytes
) == 0) {
61 fprintf (pFile
, "\n%s", LineHeader
);
63 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
66 if ((Index
% LineBytes
) == 0) {
67 fprintf (pFile
, "\n%s", LineHeader
);
69 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
72 SConfigInfo::SConfigInfo (
76 IN EFI_IFR_TYPE_VALUE Value
81 mWidth
= (UINT16
)Width
;
82 mValue
= new UINT8
[mWidth
];
88 case EFI_IFR_TYPE_NUM_SIZE_8
:
89 memcpy (mValue
, &Value
.u8
, mWidth
);
91 case EFI_IFR_TYPE_NUM_SIZE_16
:
92 memcpy (mValue
, &Value
.u16
, mWidth
);
94 case EFI_IFR_TYPE_NUM_SIZE_32
:
95 memcpy (mValue
, &Value
.u32
, mWidth
);
97 case EFI_IFR_TYPE_NUM_SIZE_64
:
98 memcpy (mValue
, &Value
.u64
, mWidth
);
100 case EFI_IFR_TYPE_BOOLEAN
:
101 memcpy (mValue
, &Value
.b
, mWidth
);
103 case EFI_IFR_TYPE_TIME
:
104 memcpy (mValue
, &Value
.time
, mWidth
);
106 case EFI_IFR_TYPE_DATE
:
107 memcpy (mValue
, &Value
.date
, mWidth
);
109 case EFI_IFR_TYPE_STRING
:
110 memcpy (mValue
, &Value
.string
, mWidth
);
112 case EFI_IFR_TYPE_OTHER
:
117 SConfigInfo::~SConfigInfo (
121 BUFFER_SAFE_FREE (mValue
);
124 SConfigItem::SConfigItem (
137 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
138 strcpy (mName
, Name
);
143 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
144 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
149 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
155 SConfigItem::SConfigItem (
162 IN EFI_IFR_TYPE_VALUE Value
172 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
173 strcpy (mName
, Name
);
178 if ((mGuid
= (EFI_GUID
*) new CHAR8
[sizeof (EFI_GUID
)]) != NULL
) {
179 memcpy (mGuid
, Guid
, sizeof (EFI_GUID
));
184 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
189 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
192 SConfigItem::~SConfigItem (
198 BUFFER_SAFE_FREE (mName
);
199 BUFFER_SAFE_FREE (mGuid
);
200 BUFFER_SAFE_FREE (mId
);
201 while (mInfoStrList
!= NULL
) {
203 mInfoStrList
= mInfoStrList
->mNext
;
205 BUFFER_SAFE_FREE (Info
);
210 CVfrBufferConfig::Register (
218 if (Select (Name
, Guid
) == 0) {
222 if ((pNew
= new SConfigItem (Name
, Guid
, Id
)) == NULL
) {
226 if (mItemListHead
== NULL
) {
227 mItemListHead
= pNew
;
228 mItemListTail
= pNew
;
230 mItemListTail
->mNext
= pNew
;
231 mItemListTail
= pNew
;
239 CVfrBufferConfig::Open (
243 mItemListPos
= mItemListHead
;
247 CVfrBufferConfig::Eof(
251 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
255 CVfrBufferConfig::Select (
263 if (Name
== NULL
|| Guid
== NULL
) {
264 mItemListPos
= mItemListHead
;
267 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
268 if ((strcmp (p
->mName
, Name
) != 0) || (memcmp (p
->mGuid
, Guid
, sizeof (EFI_GUID
)) != 0)) {
273 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
276 } else if (p
->mId
!= NULL
) {
289 CVfrBufferConfig::Write (
297 IN EFI_IFR_TYPE_VALUE Value
304 if ((Ret
= Select (Name
, Guid
)) != 0) {
310 if (Select (Name
, Guid
, Id
) != 0) {
311 if ((pItem
= new SConfigItem (Name
, Guid
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
314 if (mItemListHead
== NULL
) {
315 mItemListHead
= pItem
;
316 mItemListTail
= pItem
;
318 mItemListTail
->mNext
= pItem
;
319 mItemListTail
= pItem
;
321 mItemListPos
= pItem
;
323 // tranverse the list to find out if there's already the value for the same offset
324 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
325 if (pInfo
->mOffset
== Offset
) {
329 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
332 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
333 mItemListPos
->mInfoStrList
= pInfo
;
338 if (mItemListHead
== mItemListPos
) {
339 mItemListHead
= mItemListPos
->mNext
;
344 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
347 pItem
->mNext
= mItemListPos
->mNext
;
348 if (mItemListTail
== mItemListPos
) {
349 mItemListTail
= pItem
;
352 mItemListPos
= pItem
->mNext
;
355 case 'i' : // set info
356 if (mItemListPos
->mId
!= NULL
) {
357 delete mItemListPos
->mId
;
359 mItemListPos
->mId
= NULL
;
361 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
364 strcpy (mItemListPos
->mId
, Id
);
377 CVfrBufferConfig::Close (
384 #define BYTES_PRE_LINE 0x10
387 CVfrBufferConfig::OutputCFile (
392 CVfrBinaryOutput Output
;
401 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
402 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
405 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
407 TotalLen
= sizeof (UINT32
);
408 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
409 TotalLen
+= sizeof (UINT16
) * 2;
411 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
413 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
414 fprintf (pFile
, "\n");
415 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
418 fprintf (pFile
, "\n};\n");
421 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
422 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
423 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
425 TotalLen
= sizeof (UINT32
);
426 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
427 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
429 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
431 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
432 fprintf (pFile
, "\n");
433 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
434 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
435 if (Info
->mNext
== NULL
) {
436 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
438 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
441 fprintf (pFile
, "\n};\n");
446 CVfrBufferConfig::CVfrBufferConfig (
450 mItemListHead
= NULL
;
451 mItemListTail
= NULL
;
455 CVfrBufferConfig::~CVfrBufferConfig (
461 while (mItemListHead
!= NULL
) {
463 mItemListHead
= mItemListHead
->mNext
;
467 mItemListHead
= NULL
;
468 mItemListTail
= NULL
;
472 CVfrBufferConfig gCVfrBufferConfig
;
475 CONST CHAR8
*mTypeName
;
479 } gInternalTypesTable
[] = {
480 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
481 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
482 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
483 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
484 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
485 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
486 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
487 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
488 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
489 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
500 if (TypeName
== NULL
) {
504 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
505 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
522 while (*Str
&& *Str
== ' ') {
525 while (*Str
&& *Str
== '0') {
528 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
545 Str
= TrimHex (Str
, &IsHex
);
546 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
548 // BUG: does not handle overflow here
550 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
552 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
553 Value
+= (c
- 'a' + 10);
555 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
556 Value
+= (c
- 'A' + 10);
558 if (c
>= '0' && c
<= '9') {
567 CVfrVarDataTypeDB::RegisterNewType (
571 New
->mNext
= mDataTypeList
;
576 CVfrVarDataTypeDB::ExtractStructTypeName (
582 return VFR_RETURN_FATAL_ERROR
;
585 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
591 if (*VarStr
== '.') {
595 return VFR_RETURN_SUCCESS
;
599 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
606 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
608 ArrayIdx
= INVALID_ARRAY_INDEX
;
611 return VFR_RETURN_FATAL_ERROR
;
614 while((*VarStr
!= '\0') &&
628 return VFR_RETURN_SUCCESS
;
631 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
632 ArrayStr
[Idx
] = *VarStr
;
634 ArrayStr
[Idx
] = '\0';
636 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
637 return VFR_RETURN_DATA_STRING_ERROR
;
639 ArrayIdx
= _STR2U32 (ArrayStr
);
640 if (*VarStr
== ']') {
643 if (*VarStr
== '.') {
646 return VFR_RETURN_SUCCESS
;
648 return VFR_RETURN_DATA_STRING_ERROR
;
651 return VFR_RETURN_SUCCESS
;
655 CVfrVarDataTypeDB::GetTypeField (
656 IN CONST CHAR8
*FName
,
657 IN SVfrDataType
*Type
,
658 OUT SVfrDataField
*&Field
661 SVfrDataField
*pField
= NULL
;
663 if ((FName
== NULL
) && (Type
== NULL
)) {
664 return VFR_RETURN_FATAL_ERROR
;
667 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
669 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
670 // add code to adjust it.
672 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
673 if (strcmp (FName
, "Hour") == 0) {
675 } else if (strcmp (FName
, "Minute") == 0) {
677 } else if (strcmp (FName
, "Second") == 0) {
682 if (strcmp (pField
->mFieldName
, FName
) == 0) {
684 return VFR_RETURN_SUCCESS
;
688 return VFR_RETURN_UNDEFINED
;
692 CVfrVarDataTypeDB::GetFieldOffset (
693 IN SVfrDataField
*Field
,
699 return VFR_RETURN_FATAL_ERROR
;
703 // Framework Vfr file Array Index is from 1.
704 // But Uefi Vfr file Array Index is from 0.
706 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
708 return VFR_RETURN_ERROR_ARRARY_NUM
;
710 ArrayIdx
= ArrayIdx
- 1;
713 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
714 return VFR_RETURN_ERROR_ARRARY_NUM
;
718 // Be compatible with the current usage
719 // If ArraryIdx is not specified, the first one is used.
721 // if ArrayNum is larger than zero, ArraryIdx must be specified.
723 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
724 // return VFR_RETURN_ERROR_ARRARY_NUM;
728 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
729 return VFR_RETURN_SUCCESS
;
733 CVfrVarDataTypeDB::GetFieldWidth (
734 IN SVfrDataField
*Field
741 return Field
->mFieldType
->mType
;
745 CVfrVarDataTypeDB::GetFieldSize (
746 IN SVfrDataField
*Field
,
751 return VFR_RETURN_FATAL_ERROR
;
754 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
755 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
757 return Field
->mFieldType
->mTotalSize
;
762 CVfrVarDataTypeDB::InternalTypesListInit (
766 SVfrDataType
*New
= NULL
;
769 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
770 New
= new SVfrDataType
;
772 strcpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
);
773 New
->mType
= gInternalTypesTable
[Index
].mType
;
774 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
775 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
776 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
777 SVfrDataField
*pYearField
= new SVfrDataField
;
778 SVfrDataField
*pMonthField
= new SVfrDataField
;
779 SVfrDataField
*pDayField
= new SVfrDataField
;
781 strcpy (pYearField
->mFieldName
, "Year");
782 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
783 pYearField
->mOffset
= 0;
784 pYearField
->mNext
= pMonthField
;
785 pYearField
->mArrayNum
= 0;
787 strcpy (pMonthField
->mFieldName
, "Month");
788 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
789 pMonthField
->mOffset
= 2;
790 pMonthField
->mNext
= pDayField
;
791 pMonthField
->mArrayNum
= 0;
793 strcpy (pDayField
->mFieldName
, "Day");
794 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
795 pDayField
->mOffset
= 3;
796 pDayField
->mNext
= NULL
;
797 pDayField
->mArrayNum
= 0;
799 New
->mMembers
= pYearField
;
800 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
801 SVfrDataField
*pHoursField
= new SVfrDataField
;
802 SVfrDataField
*pMinutesField
= new SVfrDataField
;
803 SVfrDataField
*pSecondsField
= new SVfrDataField
;
805 strcpy (pHoursField
->mFieldName
, "Hours");
806 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
807 pHoursField
->mOffset
= 0;
808 pHoursField
->mNext
= pMinutesField
;
809 pHoursField
->mArrayNum
= 0;
811 strcpy (pMinutesField
->mFieldName
, "Minutes");
812 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
813 pMinutesField
->mOffset
= 1;
814 pMinutesField
->mNext
= pSecondsField
;
815 pMinutesField
->mArrayNum
= 0;
817 strcpy (pSecondsField
->mFieldName
, "Seconds");
818 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
819 pSecondsField
->mOffset
= 2;
820 pSecondsField
->mNext
= NULL
;
821 pSecondsField
->mArrayNum
= 0;
823 New
->mMembers
= pHoursField
;
824 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
825 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
826 SVfrDataField
*pFormIdField
= new SVfrDataField
;
827 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
828 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
830 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
831 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
832 pQuestionIdField
->mOffset
= 0;
833 pQuestionIdField
->mNext
= pFormIdField
;
834 pQuestionIdField
->mArrayNum
= 0;
836 strcpy (pFormIdField
->mFieldName
, "FormId");
837 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
838 pFormIdField
->mOffset
= 2;
839 pFormIdField
->mNext
= pFormSetGuidField
;
840 pFormIdField
->mArrayNum
= 0;
842 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
843 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
844 pFormSetGuidField
->mOffset
= 4;
845 pFormSetGuidField
->mNext
= pDevicePathField
;
846 pFormSetGuidField
->mArrayNum
= 0;
848 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
849 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
850 pDevicePathField
->mOffset
= 20;
851 pDevicePathField
->mNext
= NULL
;
852 pDevicePathField
->mArrayNum
= 0;
854 New
->mMembers
= pQuestionIdField
;
856 New
->mMembers
= NULL
;
859 RegisterNewType (New
);
865 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
869 mDataTypeList
= NULL
;
871 mCurrDataField
= NULL
;
872 mPackAlign
= DEFAULT_PACK_ALIGN
;
874 mFirstNewDataTypeName
= NULL
;
876 InternalTypesListInit ();
879 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
884 SVfrDataField
*pField
;
885 SVfrPackStackNode
*pPack
;
887 if (mNewDataType
!= NULL
) {
891 while (mDataTypeList
!= NULL
) {
892 pType
= mDataTypeList
;
893 mDataTypeList
= mDataTypeList
->mNext
;
894 while(pType
->mMembers
!= NULL
) {
895 pField
= pType
->mMembers
;
896 pType
->mMembers
= pType
->mMembers
->mNext
;
902 while (mPackStack
!= NULL
) {
904 mPackStack
= mPackStack
->mNext
;
910 CVfrVarDataTypeDB::Pack (
913 IN CHAR8
*Identifier
,
918 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
920 if (Action
& VFR_PACK_SHOW
) {
921 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
922 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
925 if (Action
& VFR_PACK_PUSH
) {
926 SVfrPackStackNode
*pNew
= NULL
;
928 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
929 return VFR_RETURN_FATAL_ERROR
;
931 pNew
->mNext
= mPackStack
;
935 if (Action
& VFR_PACK_POP
) {
936 SVfrPackStackNode
*pNode
= NULL
;
938 if (mPackStack
== NULL
) {
939 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
942 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
943 if (pNode
->Match (Identifier
) == TRUE
) {
944 mPackAlign
= pNode
->mNumber
;
945 mPackStack
= pNode
->mNext
;
950 if (Action
& VFR_PACK_ASSIGN
) {
951 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
952 if ((PackAlign
== 0) || (PackAlign
> 16)) {
953 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
955 mPackAlign
= PackAlign
;
959 return VFR_RETURN_SUCCESS
;
963 CVfrVarDataTypeDB::DeclareDataTypeBegin (
967 SVfrDataType
*pNewType
= NULL
;
969 pNewType
= new SVfrDataType
;
970 pNewType
->mTypeName
[0] = '\0';
971 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
972 pNewType
->mAlign
= DEFAULT_ALIGN
;
973 pNewType
->mTotalSize
= 0;
974 pNewType
->mMembers
= NULL
;
975 pNewType
->mNext
= NULL
;
977 mNewDataType
= pNewType
;
981 CVfrVarDataTypeDB::SetNewTypeName (
987 if (mNewDataType
== NULL
) {
988 return VFR_RETURN_ERROR_SKIPED
;
990 if (TypeName
== NULL
) {
991 return VFR_RETURN_FATAL_ERROR
;
993 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
994 return VFR_RETURN_INVALID_PARAMETER
;
997 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
998 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
999 return VFR_RETURN_REDEFINED
;
1003 strcpy(mNewDataType
->mTypeName
, TypeName
);
1004 return VFR_RETURN_SUCCESS
;
1008 CVfrVarDataTypeDB::DataTypeAddField (
1009 IN CHAR8
*FieldName
,
1014 SVfrDataField
*pNewField
= NULL
;
1015 SVfrDataType
*pFieldType
= NULL
;
1016 SVfrDataField
*pTmp
;
1019 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1021 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1022 return VFR_RETURN_INVALID_PARAMETER
;
1025 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1026 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1027 return VFR_RETURN_REDEFINED
;
1031 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1033 if ((pNewField
= new SVfrDataField
) == NULL
) {
1034 return VFR_RETURN_OUT_FOR_RESOURCES
;
1036 strcpy (pNewField
->mFieldName
, FieldName
);
1037 pNewField
->mFieldType
= pFieldType
;
1038 pNewField
->mArrayNum
= ArrayNum
;
1039 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1040 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1042 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1044 if (mNewDataType
->mMembers
== NULL
) {
1045 mNewDataType
->mMembers
= pNewField
;
1046 pNewField
->mNext
= NULL
;
1048 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1050 pTmp
->mNext
= pNewField
;
1051 pNewField
->mNext
= NULL
;
1054 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1055 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1057 return VFR_RETURN_SUCCESS
;
1061 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1065 if (mNewDataType
->mTypeName
[0] == '\0') {
1069 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1070 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1073 RegisterNewType (mNewDataType
);
1074 if (mFirstNewDataTypeName
== NULL
) {
1075 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1078 mNewDataType
= NULL
;
1082 CVfrVarDataTypeDB::GetDataType (
1084 OUT SVfrDataType
**DataType
1087 SVfrDataType
*pDataType
= NULL
;
1089 if (TypeName
== NULL
) {
1090 return VFR_RETURN_ERROR_SKIPED
;
1093 if (DataType
== NULL
) {
1094 return VFR_RETURN_FATAL_ERROR
;
1099 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1100 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1101 *DataType
= pDataType
;
1102 return VFR_RETURN_SUCCESS
;
1106 return VFR_RETURN_UNDEFINED
;
1110 CVfrVarDataTypeDB::GetDataTypeSize (
1115 SVfrDataType
*pDataType
= NULL
;
1118 return VFR_RETURN_FATAL_ERROR
;
1122 DataType
= DataType
& 0x0F;
1125 // For user defined data type, the size can't be got by this function.
1127 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1128 return VFR_RETURN_SUCCESS
;
1131 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1132 if (DataType
== pDataType
->mType
) {
1133 *Size
= pDataType
->mTotalSize
;
1134 return VFR_RETURN_SUCCESS
;
1138 return VFR_RETURN_UNDEFINED
;
1142 CVfrVarDataTypeDB::GetDataTypeSize (
1147 SVfrDataType
*pDataType
= NULL
;
1150 return VFR_RETURN_FATAL_ERROR
;
1155 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1156 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1157 *Size
= pDataType
->mTotalSize
;
1158 return VFR_RETURN_SUCCESS
;
1162 return VFR_RETURN_UNDEFINED
;
1166 CVfrVarDataTypeDB::GetDataFieldInfo (
1173 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1174 UINT32 ArrayIdx
, Tmp
;
1175 SVfrDataType
*pType
= NULL
;
1176 SVfrDataField
*pField
= NULL
;
1179 Type
= EFI_IFR_TYPE_OTHER
;
1182 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1183 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1186 // if it is not struct data type
1188 Type
= pType
->mType
;
1189 Size
= pType
->mTotalSize
;
1191 while (*VarStr
!= '\0') {
1192 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1193 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1194 pType
= pField
->mFieldType
;
1195 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1196 Offset
= (UINT16
) (Offset
+ Tmp
);
1197 Type
= GetFieldWidth (pField
);
1198 Size
= GetFieldSize (pField
, ArrayIdx
);
1200 return VFR_RETURN_SUCCESS
;
1204 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1205 OUT CHAR8
***NameList
,
1206 OUT UINT32
*ListSize
1210 SVfrDataType
*pType
;
1212 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1213 return VFR_RETURN_FATAL_ERROR
;
1219 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1220 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1225 if (*ListSize
== 0) {
1226 return VFR_RETURN_SUCCESS
;
1229 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1231 return VFR_RETURN_OUT_FOR_RESOURCES
;
1234 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1235 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1236 (*NameList
)[Index
] = pType
->mTypeName
;
1239 return VFR_RETURN_SUCCESS
;
1243 CVfrVarDataTypeDB::IsTypeNameDefined (
1247 SVfrDataType
*pType
;
1249 if (TypeName
== NULL
) {
1253 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1254 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1263 CVfrVarDataTypeDB::Dump (
1267 SVfrDataType
*pTNode
;
1268 SVfrDataField
*pFNode
;
1270 fprintf (File
, "\n\n***************************************************************\n");
1271 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1272 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1273 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1274 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1275 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1276 if (pFNode
->mArrayNum
> 0) {
1277 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1278 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1280 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1281 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1284 fprintf (File
, "\t\t};\n");
1285 fprintf (File
, "---------------------------------------------------------------\n");
1287 fprintf (File
, "***************************************************************\n");
1290 #ifdef CVFR_VARDATATYPEDB_DEBUG
1292 CVfrVarDataTypeDB::ParserDB (
1296 SVfrDataType
*pTNode
;
1297 SVfrDataField
*pFNode
;
1299 printf ("***************************************************************\n");
1300 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1301 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1302 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1303 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1304 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1305 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1307 printf ("\t\t};\n");
1308 printf ("---------------------------------------------------------------\n");
1310 printf ("***************************************************************\n");
1314 SVfrVarStorageNode::SVfrVarStorageNode (
1316 IN CHAR8
*StoreName
,
1317 IN EFI_VARSTORE_ID VarStoreId
,
1318 IN EFI_STRING_ID VarName
,
1326 memset (&Guid
, 0, sizeof (EFI_GUID
));
1328 if (StoreName
!= NULL
) {
1329 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1330 strcpy (mVarStoreName
, StoreName
);
1332 mVarStoreName
= NULL
;
1335 mVarStoreId
= VarStoreId
;
1336 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1337 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1338 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1339 mAssignedFlag
= Flag
;
1342 SVfrVarStorageNode::SVfrVarStorageNode (
1344 IN CHAR8
*StoreName
,
1345 IN EFI_VARSTORE_ID VarStoreId
,
1346 IN SVfrDataType
*DataType
,
1353 memset (&Guid
, 0, sizeof (EFI_GUID
));
1355 if (StoreName
!= NULL
) {
1356 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1357 strcpy (mVarStoreName
, StoreName
);
1359 mVarStoreName
= NULL
;
1362 mVarStoreId
= VarStoreId
;
1363 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1364 mStorageInfo
.mDataType
= DataType
;
1365 mAssignedFlag
= Flag
;
1368 SVfrVarStorageNode::SVfrVarStorageNode (
1369 IN CHAR8
*StoreName
,
1370 IN EFI_VARSTORE_ID VarStoreId
1373 if (StoreName
!= NULL
) {
1374 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1375 strcpy (mVarStoreName
, StoreName
);
1377 mVarStoreName
= NULL
;
1380 mVarStoreId
= VarStoreId
;
1381 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1382 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1383 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1386 SVfrVarStorageNode::~SVfrVarStorageNode (
1390 if (mVarStoreName
!= NULL
) {
1391 delete mVarStoreName
;
1394 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1395 delete mStorageInfo
.mNameSpace
.mNameTable
;
1399 CVfrDataStorage::CVfrDataStorage (
1405 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1406 mFreeVarStoreIdBitMap
[Index
] = 0;
1409 // Question ID 0 is reserved.
1410 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1412 mBufferVarStoreList
= NULL
;
1413 mEfiVarStoreList
= NULL
;
1414 mNameVarStoreList
= NULL
;
1415 mCurrVarStorageNode
= NULL
;
1416 mNewVarStorageNode
= NULL
;
1419 CVfrDataStorage::~CVfrDataStorage (
1423 SVfrVarStorageNode
*pNode
;
1425 while (mBufferVarStoreList
!= NULL
) {
1426 pNode
= mBufferVarStoreList
;
1427 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1430 while (mEfiVarStoreList
!= NULL
) {
1431 pNode
= mEfiVarStoreList
;
1432 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1435 while (mNameVarStoreList
!= NULL
) {
1436 pNode
= mNameVarStoreList
;
1437 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1440 if (mNewVarStorageNode
!= NULL
) {
1441 delete mNewVarStorageNode
;
1446 CVfrDataStorage::GetFreeVarStoreId (
1447 EFI_VFR_VARSTORE_TYPE VarType
1450 UINT32 Index
, Mask
, Offset
;
1453 // Assign the different ID range for the different type VarStore to support Framework Vfr
1456 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1458 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1460 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1464 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1465 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1470 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1471 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1472 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1473 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1477 return EFI_VARSTORE_ID_INVALID
;
1481 CVfrDataStorage::ChekVarStoreIdFree (
1482 IN EFI_VARSTORE_ID VarStoreId
1485 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1486 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1488 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1492 CVfrDataStorage::MarkVarStoreIdUsed (
1493 IN EFI_VARSTORE_ID VarStoreId
1496 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1497 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1499 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1503 CVfrDataStorage::MarkVarStoreIdUnused (
1504 IN EFI_VARSTORE_ID VarStoreId
1507 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1508 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1510 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1514 CVfrDataStorage::DeclareNameVarStoreBegin (
1515 IN CHAR8
*StoreName
,
1516 IN EFI_VARSTORE_ID VarStoreId
1519 SVfrVarStorageNode
*pNode
= NULL
;
1520 EFI_VARSTORE_ID TmpVarStoreId
;
1522 if (StoreName
== NULL
) {
1523 return VFR_RETURN_FATAL_ERROR
;
1526 if (GetVarStoreId (StoreName
, &TmpVarStoreId
) == VFR_RETURN_SUCCESS
) {
1527 return VFR_RETURN_REDEFINED
;
1530 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1531 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1533 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1534 return VFR_RETURN_VARSTOREID_REDEFINED
;
1536 MarkVarStoreIdUsed (VarStoreId
);
1539 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1540 return VFR_RETURN_UNDEFINED
;
1543 mNewVarStorageNode
= pNode
;
1545 return VFR_RETURN_SUCCESS
;
1549 CVfrDataStorage::NameTableAddItem (
1550 IN EFI_STRING_ID Item
1553 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1556 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1557 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1559 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1560 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1561 return VFR_RETURN_OUT_FOR_RESOURCES
;
1563 memcpy (NewTable
, OldTable
, TableSize
);
1564 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1567 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1568 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1570 return VFR_RETURN_SUCCESS
;
1574 CVfrDataStorage::DeclareNameVarStoreEnd (
1578 mNewVarStorageNode
->mGuid
= *Guid
;
1579 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1580 mNameVarStoreList
= mNewVarStorageNode
;
1582 mNewVarStorageNode
= NULL
;
1584 return VFR_RETURN_SUCCESS
;
1588 CVfrDataStorage::DeclareEfiVarStore (
1589 IN CHAR8
*StoreName
,
1591 IN EFI_STRING_ID NameStrId
,
1596 SVfrVarStorageNode
*pNode
;
1597 EFI_VARSTORE_ID VarStoreId
;
1599 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1600 return VFR_RETURN_FATAL_ERROR
;
1603 if (VarSize
> sizeof (UINT64
)) {
1604 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1607 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1608 return VFR_RETURN_REDEFINED
;
1611 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1612 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1613 return VFR_RETURN_OUT_FOR_RESOURCES
;
1616 pNode
->mNext
= mEfiVarStoreList
;
1617 mEfiVarStoreList
= pNode
;
1619 return VFR_RETURN_SUCCESS
;
1623 CVfrDataStorage::DeclareBufferVarStore (
1624 IN CHAR8
*StoreName
,
1626 IN CVfrVarDataTypeDB
*DataTypeDB
,
1628 IN EFI_VARSTORE_ID VarStoreId
,
1632 SVfrVarStorageNode
*pNew
= NULL
;
1633 SVfrDataType
*pDataType
= NULL
;
1634 EFI_VARSTORE_ID TempVarStoreId
;
1636 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1637 return VFR_RETURN_FATAL_ERROR
;
1640 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1641 return VFR_RETURN_REDEFINED
;
1644 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1646 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1647 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1649 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1650 return VFR_RETURN_VARSTOREID_REDEFINED
;
1652 MarkVarStoreIdUsed (VarStoreId
);
1655 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1656 return VFR_RETURN_OUT_FOR_RESOURCES
;
1659 pNew
->mNext
= mBufferVarStoreList
;
1660 mBufferVarStoreList
= pNew
;
1662 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1663 return VFR_RETURN_FATAL_ERROR
;
1666 return VFR_RETURN_SUCCESS
;
1670 CVfrDataStorage::GetVarStoreByDataType (
1671 IN CHAR8
*DataTypeName
,
1672 OUT SVfrVarStorageNode
**VarNode
,
1673 IN EFI_GUID
*VarGuid
1676 SVfrVarStorageNode
*pNode
;
1677 SVfrVarStorageNode
*MatchNode
;
1680 // Framework VFR uses Data type name as varstore name, so don't need check again.
1682 if (VfrCompatibleMode
) {
1683 return VFR_RETURN_UNDEFINED
;
1687 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1688 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1692 if ((VarGuid
!= NULL
)) {
1693 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1695 return VFR_RETURN_SUCCESS
;
1698 if (MatchNode
== NULL
) {
1702 // More than one varstores referred the same data structures.
1704 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1709 if (MatchNode
== NULL
) {
1710 return VFR_RETURN_UNDEFINED
;
1713 *VarNode
= MatchNode
;
1714 return VFR_RETURN_SUCCESS
;
1718 CVfrDataStorage::CheckGuidField (
1719 IN SVfrVarStorageNode
*pNode
,
1720 IN EFI_GUID
*StoreGuid
,
1721 IN BOOLEAN
*HasFoundOne
,
1722 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1725 if (StoreGuid
!= NULL
) {
1727 // If has guid info, compare the guid filed.
1729 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1731 // Both name and guid are same, this this varstore.
1733 mCurrVarStorageNode
= pNode
;
1734 *ReturnCode
= VFR_RETURN_SUCCESS
;
1739 // Not has Guid field, check whether this name is the only one.
1743 // The name has conflict, return name redefined.
1745 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1749 *HasFoundOne
= TRUE
;
1750 mCurrVarStorageNode
= pNode
;
1757 Base on the input store name and guid to find the varstore id.
1759 If both name and guid are inputed, base on the name and guid to
1760 found the varstore. If only name inputed, base on the name to
1761 found the varstore and go on to check whether more than one varstore
1762 has the same name. If only has found one varstore, return this
1763 varstore; if more than one varstore has same name, return varstore
1764 name redefined error. If no varstore found by varstore name, call
1765 function GetVarStoreByDataType and use inputed varstore name as
1766 data type name to search.
1769 CVfrDataStorage::GetVarStoreId (
1770 IN CHAR8
*StoreName
,
1771 OUT EFI_VARSTORE_ID
*VarStoreId
,
1772 IN EFI_GUID
*StoreGuid
1775 EFI_VFR_RETURN_CODE ReturnCode
;
1776 SVfrVarStorageNode
*pNode
;
1777 BOOLEAN HasFoundOne
= FALSE
;
1779 mCurrVarStorageNode
= NULL
;
1781 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1782 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1783 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1784 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1790 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1791 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1792 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1793 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1799 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1800 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1801 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1802 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1809 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1810 return VFR_RETURN_SUCCESS
;
1813 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1816 // Assume that Data strucutre name is used as StoreName, and check again.
1818 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1819 if (pNode
!= NULL
) {
1820 mCurrVarStorageNode
= pNode
;
1821 *VarStoreId
= pNode
->mVarStoreId
;
1828 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1829 IN EFI_VARSTORE_ID VarStoreId
,
1830 OUT CHAR8
**DataTypeName
1833 SVfrVarStorageNode
*pNode
;
1835 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1836 return VFR_RETURN_FATAL_ERROR
;
1839 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1840 if (pNode
->mVarStoreId
== VarStoreId
) {
1841 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1842 return VFR_RETURN_SUCCESS
;
1846 return VFR_RETURN_UNDEFINED
;
1849 EFI_VFR_VARSTORE_TYPE
1850 CVfrDataStorage::GetVarStoreType (
1851 IN EFI_VARSTORE_ID VarStoreId
1854 SVfrVarStorageNode
*pNode
;
1855 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1857 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1859 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1860 return VarStoreType
;
1863 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1864 if (pNode
->mVarStoreId
== VarStoreId
) {
1865 VarStoreType
= pNode
->mVarStoreType
;
1866 return VarStoreType
;
1870 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1871 if (pNode
->mVarStoreId
== VarStoreId
) {
1872 VarStoreType
= pNode
->mVarStoreType
;
1873 return VarStoreType
;
1877 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1878 if (pNode
->mVarStoreId
== VarStoreId
) {
1879 VarStoreType
= pNode
->mVarStoreType
;
1880 return VarStoreType
;
1884 return VarStoreType
;
1888 CVfrDataStorage::GetVarStoreGuid (
1889 IN EFI_VARSTORE_ID VarStoreId
1892 SVfrVarStorageNode
*pNode
;
1897 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1901 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1902 if (pNode
->mVarStoreId
== VarStoreId
) {
1903 VarGuid
= &pNode
->mGuid
;
1908 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1909 if (pNode
->mVarStoreId
== VarStoreId
) {
1910 VarGuid
= &pNode
->mGuid
;
1915 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1916 if (pNode
->mVarStoreId
== VarStoreId
) {
1917 VarGuid
= &pNode
->mGuid
;
1926 CVfrDataStorage::GetVarStoreName (
1927 IN EFI_VARSTORE_ID VarStoreId
,
1928 OUT CHAR8
**VarStoreName
1931 SVfrVarStorageNode
*pNode
;
1933 if (VarStoreName
== NULL
) {
1934 return VFR_RETURN_FATAL_ERROR
;
1937 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1938 if (pNode
->mVarStoreId
== VarStoreId
) {
1939 *VarStoreName
= pNode
->mVarStoreName
;
1940 return VFR_RETURN_SUCCESS
;
1944 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1945 if (pNode
->mVarStoreId
== VarStoreId
) {
1946 *VarStoreName
= pNode
->mVarStoreName
;
1947 return VFR_RETURN_SUCCESS
;
1951 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1952 if (pNode
->mVarStoreId
== VarStoreId
) {
1953 *VarStoreName
= pNode
->mVarStoreName
;
1954 return VFR_RETURN_SUCCESS
;
1958 *VarStoreName
= NULL
;
1959 return VFR_RETURN_UNDEFINED
;
1963 CVfrDataStorage::GetEfiVarStoreInfo (
1964 IN OUT EFI_VARSTORE_INFO
*Info
1968 return VFR_RETURN_FATAL_ERROR
;
1971 if (mCurrVarStorageNode
== NULL
) {
1972 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1975 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1976 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1977 switch (Info
->mVarTotalSize
) {
1979 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1982 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1985 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1988 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1991 return VFR_RETURN_FATAL_ERROR
;
1994 return VFR_RETURN_SUCCESS
;
1998 CVfrDataStorage::GetNameVarStoreInfo (
1999 OUT EFI_VARSTORE_INFO
*Info
,
2004 return VFR_RETURN_FATAL_ERROR
;
2007 if (mCurrVarStorageNode
== NULL
) {
2008 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2012 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2014 if (VfrCompatibleMode
) {
2016 return VFR_RETURN_ERROR_ARRARY_NUM
;
2021 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2023 return VFR_RETURN_SUCCESS
;
2026 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2027 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2029 IN EFI_STRING_ID DefaultStoreNameId
,
2033 mObjBinAddr
= ObjBinAddr
;
2035 if (RefName
!= NULL
) {
2036 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2037 strcpy (mRefName
, RefName
);
2043 mDefaultId
= DefaultId
;
2044 mDefaultStoreNameId
= DefaultStoreNameId
;
2047 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2051 if (mRefName
!= NULL
) {
2056 CVfrDefaultStore::CVfrDefaultStore (
2060 mDefaultStoreList
= NULL
;
2063 CVfrDefaultStore::~CVfrDefaultStore (
2067 SVfrDefaultStoreNode
*pTmp
= NULL
;
2069 while (mDefaultStoreList
!= NULL
) {
2070 pTmp
= mDefaultStoreList
;
2071 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2077 CVfrDefaultStore::RegisterDefaultStore (
2078 IN CHAR8
*ObjBinAddr
,
2080 IN EFI_STRING_ID DefaultStoreNameId
,
2084 SVfrDefaultStoreNode
*pNode
= NULL
;
2086 if (RefName
== NULL
) {
2087 return VFR_RETURN_FATAL_ERROR
;
2090 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2091 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2092 return VFR_RETURN_REDEFINED
;
2096 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2097 return VFR_RETURN_OUT_FOR_RESOURCES
;
2100 pNode
->mNext
= mDefaultStoreList
;
2101 mDefaultStoreList
= pNode
;
2103 return VFR_RETURN_SUCCESS
;
2107 * assign new reference name or new default store name id only if
2108 * the original is invalid
2111 CVfrDefaultStore::ReRegisterDefaultStoreById (
2112 IN UINT16 DefaultId
,
2114 IN EFI_STRING_ID DefaultStoreNameId
2117 SVfrDefaultStoreNode
*pNode
= NULL
;
2119 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2120 if (pNode
->mDefaultId
== DefaultId
) {
2125 if (pNode
== NULL
) {
2126 return VFR_RETURN_UNDEFINED
;
2128 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2129 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2130 if (pNode
->mObjBinAddr
!= NULL
) {
2131 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2134 return VFR_RETURN_REDEFINED
;
2137 if (RefName
!= NULL
) {
2138 delete pNode
->mRefName
;
2139 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2140 if (pNode
->mRefName
!= NULL
) {
2141 strcpy (pNode
->mRefName
, RefName
);
2146 return VFR_RETURN_SUCCESS
;
2150 CVfrDefaultStore::DefaultIdRegistered (
2154 SVfrDefaultStoreNode
*pNode
= NULL
;
2156 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2157 if (pNode
->mDefaultId
== DefaultId
) {
2166 CVfrDefaultStore::GetDefaultId (
2168 OUT UINT16
*DefaultId
2171 SVfrDefaultStoreNode
*pTmp
= NULL
;
2173 if (DefaultId
== NULL
) {
2174 return VFR_RETURN_FATAL_ERROR
;
2177 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2178 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2179 *DefaultId
= pTmp
->mDefaultId
;
2180 return VFR_RETURN_SUCCESS
;
2184 return VFR_RETURN_UNDEFINED
;
2188 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2189 IN EFI_VARSTORE_ID DefaultId
,
2190 IN EFI_VARSTORE_INFO
&Info
,
2191 IN CHAR8
*VarStoreName
,
2192 IN EFI_GUID
*VarStoreGuid
,
2194 IN EFI_IFR_TYPE_VALUE Value
2197 SVfrDefaultStoreNode
*pNode
= NULL
;
2198 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2199 INTN Returnvalue
= 0;
2201 if (VarStoreName
== NULL
) {
2202 return VFR_RETURN_FATAL_ERROR
;
2205 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2206 if (pNode
->mDefaultId
== DefaultId
) {
2211 if (pNode
== NULL
) {
2212 return VFR_RETURN_UNDEFINED
;
2215 gCVfrBufferConfig
.Open ();
2217 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2218 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2219 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2224 gCVfrBufferConfig
.Close ();
2226 return VFR_RETURN_SUCCESS
;
2229 gCVfrBufferConfig
.Close ();
2230 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2233 SVfrRuleNode::SVfrRuleNode (
2238 if (RuleName
!= NULL
) {
2239 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2240 strcpy (mRuleName
, RuleName
);
2249 SVfrRuleNode::~SVfrRuleNode (
2253 if (mRuleName
!= NULL
) {
2258 CVfrRulesDB::CVfrRulesDB ()
2261 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2264 CVfrRulesDB::~CVfrRulesDB ()
2266 SVfrRuleNode
*pNode
;
2268 while(mRuleList
!= NULL
) {
2270 mRuleList
= mRuleList
->mNext
;
2276 CVfrRulesDB::RegisterRule (
2282 if (RuleName
== NULL
) {
2286 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2292 pNew
->mNext
= mRuleList
;
2297 CVfrRulesDB::GetRuleId (
2301 SVfrRuleNode
*pNode
;
2303 if (RuleName
== NULL
) {
2304 return EFI_RULE_ID_INVALID
;
2307 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2308 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2309 return pNode
->mRuleId
;
2313 return EFI_RULE_ID_INVALID
;
2316 CVfrRulesDB gCVfrRulesDB
;
2318 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2322 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2323 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2324 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2325 mVarType
= EFI_IFR_TYPE_OTHER
;
2329 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2330 IN EFI_VARSTORE_INFO
&Info
2333 mVarStoreId
= Info
.mVarStoreId
;
2334 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2335 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2336 mVarType
= Info
.mVarType
;
2337 mVarTotalSize
= Info
.mVarTotalSize
;
2341 EFI_VARSTORE_INFO::operator == (
2342 IN EFI_VARSTORE_INFO
*Info
2345 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2346 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2347 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2348 (mVarType
== Info
->mVarType
) &&
2349 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2356 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2359 CVfrQuestionDB::GetFreeQuestionId (
2363 UINT32 Index
, Mask
, Offset
;
2365 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2366 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2371 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2372 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2373 mFreeQIdBitMap
[Index
] |= Mask
;
2374 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2378 return EFI_QUESTION_ID_INVALID
;
2382 CVfrQuestionDB::ChekQuestionIdFree (
2383 IN EFI_QUESTION_ID QId
2386 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2387 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2389 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2393 CVfrQuestionDB::MarkQuestionIdUsed (
2394 IN EFI_QUESTION_ID QId
2397 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2398 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2400 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2404 CVfrQuestionDB::MarkQuestionIdUnused (
2405 IN EFI_QUESTION_ID QId
2408 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2409 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2411 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2414 SVfrQuestionNode::SVfrQuestionNode (
2422 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2425 mQtype
= QUESTION_NORMAL
;
2428 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2429 strcpy (mName
, "$DEFAULT");
2431 mName
= new CHAR8
[strlen (Name
) + 1];
2432 strcpy (mName
, Name
);
2435 if (VarIdStr
!= NULL
) {
2436 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2437 strcpy (mVarIdStr
, VarIdStr
);
2439 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2440 strcpy (mVarIdStr
, "$");
2444 SVfrQuestionNode::~SVfrQuestionNode (
2448 if (mName
!= NULL
) {
2452 if (mVarIdStr
!= NULL
) {
2457 CVfrQuestionDB::CVfrQuestionDB ()
2461 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2462 mFreeQIdBitMap
[Index
] = 0;
2465 // Question ID 0 is reserved.
2466 mFreeQIdBitMap
[0] = 0x80000000;
2467 mQuestionList
= NULL
;
2470 CVfrQuestionDB::~CVfrQuestionDB ()
2472 SVfrQuestionNode
*pNode
;
2474 while (mQuestionList
!= NULL
) {
2475 pNode
= mQuestionList
;
2476 mQuestionList
= mQuestionList
->mNext
;
2482 // Reset to init state
2485 CVfrQuestionDB::ResetInit(
2490 SVfrQuestionNode
*pNode
;
2492 while (mQuestionList
!= NULL
) {
2493 pNode
= mQuestionList
;
2494 mQuestionList
= mQuestionList
->mNext
;
2498 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2499 mFreeQIdBitMap
[Index
] = 0;
2502 // Question ID 0 is reserved.
2503 mFreeQIdBitMap
[0] = 0x80000000;
2504 mQuestionList
= NULL
;
2508 CVfrQuestionDB::PrintAllQuestion (
2512 SVfrQuestionNode
*pNode
= NULL
;
2514 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2515 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2520 CVfrQuestionDB::RegisterQuestion (
2523 IN OUT EFI_QUESTION_ID
&QuestionId
2526 SVfrQuestionNode
*pNode
= NULL
;
2528 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2529 return VFR_RETURN_REDEFINED
;
2532 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2533 return VFR_RETURN_OUT_FOR_RESOURCES
;
2536 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2537 QuestionId
= GetFreeQuestionId ();
2540 // For Framework Vfr, don't check question ID conflict.
2542 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2544 return VFR_RETURN_QUESTIONID_REDEFINED
;
2546 MarkQuestionIdUsed (QuestionId
);
2548 pNode
->mQuestionId
= QuestionId
;
2550 pNode
->mNext
= mQuestionList
;
2551 mQuestionList
= pNode
;
2553 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2555 return VFR_RETURN_SUCCESS
;
2559 CVfrQuestionDB::RegisterOldDateQuestion (
2560 IN CHAR8
*YearVarId
,
2561 IN CHAR8
*MonthVarId
,
2563 IN OUT EFI_QUESTION_ID
&QuestionId
2566 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2569 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2573 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2576 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2579 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2583 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2584 QuestionId
= GetFreeQuestionId ();
2586 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2589 MarkQuestionIdUsed (QuestionId
);
2592 pNode
[0]->mQuestionId
= QuestionId
;
2593 pNode
[1]->mQuestionId
= QuestionId
;
2594 pNode
[2]->mQuestionId
= QuestionId
;
2595 pNode
[0]->mQtype
= QUESTION_DATE
;
2596 pNode
[1]->mQtype
= QUESTION_DATE
;
2597 pNode
[2]->mQtype
= QUESTION_DATE
;
2598 pNode
[0]->mNext
= pNode
[1];
2599 pNode
[1]->mNext
= pNode
[2];
2600 pNode
[2]->mNext
= mQuestionList
;
2601 mQuestionList
= pNode
[0];
2603 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2604 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2605 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2610 for (Index
= 0; Index
< 3; Index
++) {
2611 if (pNode
[Index
] != NULL
) {
2612 delete pNode
[Index
];
2615 QuestionId
= EFI_QUESTION_ID_INVALID
;
2619 CVfrQuestionDB::RegisterNewDateQuestion (
2621 IN CHAR8
*BaseVarId
,
2622 IN OUT EFI_QUESTION_ID
&QuestionId
2625 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2627 CHAR8
*VarIdStr
[3] = {NULL
, };
2630 if (BaseVarId
== NULL
&& Name
== NULL
) {
2631 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2632 QuestionId
= GetFreeQuestionId ();
2634 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2637 MarkQuestionIdUsed (QuestionId
);
2642 if (BaseVarId
!= NULL
) {
2643 Len
= strlen (BaseVarId
);
2645 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2646 if (VarIdStr
[0] != NULL
) {
2647 strcpy (VarIdStr
[0], BaseVarId
);
2648 strcat (VarIdStr
[0], ".Year");
2650 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2651 if (VarIdStr
[1] != NULL
) {
2652 strcpy (VarIdStr
[1], BaseVarId
);
2653 strcat (VarIdStr
[1], ".Month");
2655 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2656 if (VarIdStr
[2] != NULL
) {
2657 strcpy (VarIdStr
[2], BaseVarId
);
2658 strcat (VarIdStr
[2], ".Day");
2661 Len
= strlen (Name
);
2663 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2664 if (VarIdStr
[0] != NULL
) {
2665 strcpy (VarIdStr
[0], Name
);
2666 strcat (VarIdStr
[0], ".Year");
2668 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2669 if (VarIdStr
[1] != NULL
) {
2670 strcpy (VarIdStr
[1], Name
);
2671 strcat (VarIdStr
[1], ".Month");
2673 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2674 if (VarIdStr
[2] != NULL
) {
2675 strcpy (VarIdStr
[2], Name
);
2676 strcat (VarIdStr
[2], ".Day");
2680 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2683 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2686 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2690 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2691 QuestionId
= GetFreeQuestionId ();
2693 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2696 MarkQuestionIdUsed (QuestionId
);
2699 pNode
[0]->mQuestionId
= QuestionId
;
2700 pNode
[1]->mQuestionId
= QuestionId
;
2701 pNode
[2]->mQuestionId
= QuestionId
;
2702 pNode
[0]->mQtype
= QUESTION_DATE
;
2703 pNode
[1]->mQtype
= QUESTION_DATE
;
2704 pNode
[2]->mQtype
= QUESTION_DATE
;
2705 pNode
[0]->mNext
= pNode
[1];
2706 pNode
[1]->mNext
= pNode
[2];
2707 pNode
[2]->mNext
= mQuestionList
;
2708 mQuestionList
= pNode
[0];
2710 for (Index
= 0; Index
< 3; Index
++) {
2711 if (VarIdStr
[Index
] != NULL
) {
2712 delete VarIdStr
[Index
];
2716 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2717 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2718 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2723 for (Index
= 0; Index
< 3; Index
++) {
2724 if (pNode
[Index
] != NULL
) {
2725 delete pNode
[Index
];
2728 if (VarIdStr
[Index
] != NULL
) {
2729 delete VarIdStr
[Index
];
2735 CVfrQuestionDB::RegisterOldTimeQuestion (
2736 IN CHAR8
*HourVarId
,
2737 IN CHAR8
*MinuteVarId
,
2738 IN CHAR8
*SecondVarId
,
2739 IN OUT EFI_QUESTION_ID
&QuestionId
2742 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2745 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2749 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2752 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2755 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_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_TIME
;
2772 pNode
[1]->mQtype
= QUESTION_TIME
;
2773 pNode
[2]->mQtype
= QUESTION_TIME
;
2774 pNode
[0]->mNext
= pNode
[1];
2775 pNode
[1]->mNext
= pNode
[2];
2776 pNode
[2]->mNext
= mQuestionList
;
2777 mQuestionList
= pNode
[0];
2779 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2780 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2781 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2786 for (Index
= 0; Index
< 3; Index
++) {
2787 if (pNode
[Index
] != NULL
) {
2788 delete pNode
[Index
];
2791 QuestionId
= EFI_QUESTION_ID_INVALID
;
2795 CVfrQuestionDB::RegisterNewTimeQuestion (
2797 IN CHAR8
*BaseVarId
,
2798 IN OUT EFI_QUESTION_ID
&QuestionId
2801 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2803 CHAR8
*VarIdStr
[3] = {NULL
, };
2806 if (BaseVarId
== NULL
&& Name
== NULL
) {
2807 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2808 QuestionId
= GetFreeQuestionId ();
2810 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2813 MarkQuestionIdUsed (QuestionId
);
2818 if (BaseVarId
!= NULL
) {
2819 Len
= strlen (BaseVarId
);
2821 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2822 if (VarIdStr
[0] != NULL
) {
2823 strcpy (VarIdStr
[0], BaseVarId
);
2824 strcat (VarIdStr
[0], ".Hour");
2826 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2827 if (VarIdStr
[1] != NULL
) {
2828 strcpy (VarIdStr
[1], BaseVarId
);
2829 strcat (VarIdStr
[1], ".Minute");
2831 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2832 if (VarIdStr
[2] != NULL
) {
2833 strcpy (VarIdStr
[2], BaseVarId
);
2834 strcat (VarIdStr
[2], ".Second");
2837 Len
= strlen (Name
);
2839 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2840 if (VarIdStr
[0] != NULL
) {
2841 strcpy (VarIdStr
[0], Name
);
2842 strcat (VarIdStr
[0], ".Hour");
2844 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2845 if (VarIdStr
[1] != NULL
) {
2846 strcpy (VarIdStr
[1], Name
);
2847 strcat (VarIdStr
[1], ".Minute");
2849 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2850 if (VarIdStr
[2] != NULL
) {
2851 strcpy (VarIdStr
[2], Name
);
2852 strcat (VarIdStr
[2], ".Second");
2856 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2859 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2862 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2866 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2867 QuestionId
= GetFreeQuestionId ();
2869 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2872 MarkQuestionIdUsed (QuestionId
);
2875 pNode
[0]->mQuestionId
= QuestionId
;
2876 pNode
[1]->mQuestionId
= QuestionId
;
2877 pNode
[2]->mQuestionId
= QuestionId
;
2878 pNode
[0]->mQtype
= QUESTION_TIME
;
2879 pNode
[1]->mQtype
= QUESTION_TIME
;
2880 pNode
[2]->mQtype
= QUESTION_TIME
;
2881 pNode
[0]->mNext
= pNode
[1];
2882 pNode
[1]->mNext
= pNode
[2];
2883 pNode
[2]->mNext
= mQuestionList
;
2884 mQuestionList
= pNode
[0];
2886 for (Index
= 0; Index
< 3; Index
++) {
2887 if (VarIdStr
[Index
] != NULL
) {
2888 delete VarIdStr
[Index
];
2892 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2893 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2894 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2899 for (Index
= 0; Index
< 3; Index
++) {
2900 if (pNode
[Index
] != NULL
) {
2901 delete pNode
[Index
];
2904 if (VarIdStr
[Index
] != NULL
) {
2905 delete VarIdStr
[Index
];
2911 CVfrQuestionDB::RegisterRefQuestion (
2913 IN CHAR8
*BaseVarId
,
2914 IN OUT EFI_QUESTION_ID
&QuestionId
2917 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2919 CHAR8
*VarIdStr
[4] = {NULL
, };
2922 if (BaseVarId
== NULL
&& Name
== NULL
) {
2926 if (BaseVarId
!= NULL
) {
2927 Len
= strlen (BaseVarId
);
2929 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2930 if (VarIdStr
[0] != NULL
) {
2931 strcpy (VarIdStr
[0], BaseVarId
);
2932 strcat (VarIdStr
[0], ".QuestionId");
2934 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2935 if (VarIdStr
[1] != NULL
) {
2936 strcpy (VarIdStr
[1], BaseVarId
);
2937 strcat (VarIdStr
[1], ".FormId");
2939 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2940 if (VarIdStr
[2] != NULL
) {
2941 strcpy (VarIdStr
[2], BaseVarId
);
2942 strcat (VarIdStr
[2], ".FormSetGuid");
2944 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2945 if (VarIdStr
[3] != NULL
) {
2946 strcpy (VarIdStr
[3], BaseVarId
);
2947 strcat (VarIdStr
[3], ".DevicePath");
2950 Len
= strlen (Name
);
2952 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2953 if (VarIdStr
[0] != NULL
) {
2954 strcpy (VarIdStr
[0], Name
);
2955 strcat (VarIdStr
[0], ".QuestionId");
2957 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2958 if (VarIdStr
[1] != NULL
) {
2959 strcpy (VarIdStr
[1], Name
);
2960 strcat (VarIdStr
[1], ".FormId");
2962 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2963 if (VarIdStr
[2] != NULL
) {
2964 strcpy (VarIdStr
[2], Name
);
2965 strcat (VarIdStr
[2], ".FormSetGuid");
2967 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2968 if (VarIdStr
[3] != NULL
) {
2969 strcpy (VarIdStr
[3], Name
);
2970 strcat (VarIdStr
[3], ".DevicePath");
2974 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
2977 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
2980 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
2983 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
2987 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2988 QuestionId
= GetFreeQuestionId ();
2990 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2993 MarkQuestionIdUsed (QuestionId
);
2996 pNode
[0]->mQuestionId
= QuestionId
;
2997 pNode
[1]->mQuestionId
= QuestionId
;
2998 pNode
[2]->mQuestionId
= QuestionId
;
2999 pNode
[3]->mQuestionId
= QuestionId
;
3000 pNode
[0]->mQtype
= QUESTION_REF
;
3001 pNode
[1]->mQtype
= QUESTION_REF
;
3002 pNode
[2]->mQtype
= QUESTION_REF
;
3003 pNode
[3]->mQtype
= QUESTION_REF
;
3004 pNode
[0]->mNext
= pNode
[1];
3005 pNode
[1]->mNext
= pNode
[2];
3006 pNode
[2]->mNext
= pNode
[3];
3007 pNode
[3]->mNext
= mQuestionList
;
3008 mQuestionList
= pNode
[0];
3010 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3011 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3012 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3013 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
3018 for (Index
= 0; Index
< 4; Index
++) {
3019 if (pNode
[Index
] != NULL
) {
3020 delete pNode
[Index
];
3023 if (VarIdStr
[Index
] != NULL
) {
3024 delete VarIdStr
[Index
];
3030 CVfrQuestionDB::UpdateQuestionId (
3031 IN EFI_QUESTION_ID QId
,
3032 IN EFI_QUESTION_ID NewQId
3035 SVfrQuestionNode
*pNode
= NULL
;
3037 if (QId
== NewQId
) {
3039 return VFR_RETURN_SUCCESS
;
3043 // For Framework Vfr, don't check question ID conflict.
3045 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3046 return VFR_RETURN_REDEFINED
;
3049 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3050 if (pNode
->mQuestionId
== QId
) {
3055 if (pNode
== NULL
) {
3056 return VFR_RETURN_UNDEFINED
;
3059 MarkQuestionIdUnused (QId
);
3060 pNode
->mQuestionId
= NewQId
;
3061 MarkQuestionIdUsed (NewQId
);
3063 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3065 return VFR_RETURN_SUCCESS
;
3069 CVfrQuestionDB::GetQuestionId (
3072 OUT EFI_QUESTION_ID
&QuestionId
,
3073 OUT UINT32
&BitMask
,
3074 OUT EFI_QUESION_TYPE
*QType
3077 SVfrQuestionNode
*pNode
;
3079 QuestionId
= EFI_QUESTION_ID_INVALID
;
3080 BitMask
= 0x00000000;
3081 if (QType
!= NULL
) {
3082 *QType
= QUESTION_NORMAL
;
3085 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3089 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3091 if (strcmp (pNode
->mName
, Name
) != 0) {
3096 if (VarIdStr
!= NULL
) {
3097 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3102 QuestionId
= pNode
->mQuestionId
;
3103 BitMask
= pNode
->mBitMask
;
3104 if (QType
!= NULL
) {
3105 *QType
= pNode
->mQtype
;
3114 CVfrQuestionDB::FindQuestion (
3115 IN EFI_QUESTION_ID QuestionId
3118 SVfrQuestionNode
*pNode
;
3120 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3121 return VFR_RETURN_INVALID_PARAMETER
;
3124 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3125 if (pNode
->mQuestionId
== QuestionId
) {
3126 return VFR_RETURN_SUCCESS
;
3130 return VFR_RETURN_UNDEFINED
;
3134 CVfrQuestionDB::FindQuestion (
3138 SVfrQuestionNode
*pNode
;
3141 return VFR_RETURN_FATAL_ERROR
;
3144 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3145 if (strcmp (pNode
->mName
, Name
) == 0) {
3146 return VFR_RETURN_SUCCESS
;
3150 return VFR_RETURN_UNDEFINED
;
3153 CVfrStringDB::CVfrStringDB ()
3155 mStringFileName
= NULL
;
3158 CVfrStringDB::~CVfrStringDB ()
3160 if (mStringFileName
!= NULL
) {
3161 delete mStringFileName
;
3163 mStringFileName
= NULL
;
3168 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3172 if (StringFileName
== NULL
) {
3176 FileLen
= strlen (StringFileName
) + 1;
3177 mStringFileName
= new CHAR8
[FileLen
];
3178 if (mStringFileName
== NULL
) {
3182 strcpy (mStringFileName
, StringFileName
);
3183 mStringFileName
[FileLen
- 1] = '\0';
3188 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3189 from a set of supported languages.
3191 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3192 contains a set of language codes.
3193 @param[in] Language A variable that contains pointers to Null-terminated
3194 ASCII strings that contain one language codes.
3196 @retval FALSE The best matching language could not be found in SupportedLanguages.
3197 @retval TRUE The best matching language could be found in SupportedLanguages.
3201 CVfrStringDB::GetBestLanguage (
3202 IN CONST CHAR8
*SupportedLanguages
,
3206 UINTN CompareLength
;
3207 UINTN LanguageLength
;
3208 CONST CHAR8
*Supported
;
3210 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3215 // Determine the length of the first RFC 4646 language code in Language
3217 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3220 // Trim back the length of Language used until it is empty
3222 while (LanguageLength
> 0) {
3224 // Loop through all language codes in SupportedLanguages
3226 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3228 // Skip ';' characters in Supported
3230 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3232 // Determine the length of the next language code in Supported
3234 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3236 // If Language is longer than the Supported, then skip to the next language
3238 if (LanguageLength
> CompareLength
) {
3243 // See if the first LanguageLength characters in Supported match Language
3245 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3251 // Trim Language from the right to the next '-' character
3253 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3257 // No matches were found
3264 CVfrStringDB::GetVarStoreNameFormStringId (
3265 IN EFI_STRING_ID StringId
3268 FILE *pInFile
= NULL
;
3273 CHAR16
*UnicodeString
;
3274 CHAR8
*VarStoreName
= NULL
;
3278 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3280 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3282 if (mStringFileName
== '\0' ) {
3286 if ((pInFile
= fopen (mStringFileName
, "rb")) == NULL
) {
3293 fseek (pInFile
, 0, SEEK_END
);
3294 Length
= ftell (pInFile
);
3295 fseek (pInFile
, 0, SEEK_SET
);
3300 StringPtr
= new UINT8
[Length
];
3301 if (StringPtr
== NULL
) {
3305 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3308 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3310 // Check the String package.
3312 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3318 // Search the language, get best language base on RFC 4647 matching algorithm.
3320 Current
= StringPtr
;
3321 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3322 Current
+= PkgHeader
->Header
.Length
;
3323 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3325 // If can't find string package base on language, just return the first string package.
3327 if (Current
- StringPtr
>= Length
) {
3328 Current
= StringPtr
;
3329 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3334 Current
+= PkgHeader
->HdrSize
;
3336 // Find the string block according the stringId.
3338 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3339 if (Status
!= EFI_SUCCESS
) {
3345 // Get varstore name according the string type.
3347 switch (BlockType
) {
3348 case EFI_HII_SIBT_STRING_SCSU
:
3349 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3350 case EFI_HII_SIBT_STRINGS_SCSU
:
3351 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3352 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3353 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3354 strcpy (VarStoreName
, StringName
);
3356 case EFI_HII_SIBT_STRING_UCS2
:
3357 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3358 case EFI_HII_SIBT_STRINGS_UCS2
:
3359 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3360 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3361 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3362 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3363 VarStoreName
= DestTmp
;
3364 while (*UnicodeString
!= '\0') {
3365 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3375 return VarStoreName
;
3379 CVfrStringDB::FindStringBlock (
3380 IN UINT8
*StringData
,
3381 IN EFI_STRING_ID StringId
,
3382 OUT UINT32
*StringTextOffset
,
3383 OUT UINT8
*BlockType
3387 EFI_STRING_ID CurrentStringId
;
3390 UINT8
*StringTextPtr
;
3395 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3399 CurrentStringId
= 1;
3402 // Parse the string blocks to get the string text and font.
3404 BlockHdr
= StringData
;
3407 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3408 switch (*BlockHdr
) {
3409 case EFI_HII_SIBT_STRING_SCSU
:
3410 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3411 StringTextPtr
= BlockHdr
+ Offset
;
3412 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3416 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3417 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3418 StringTextPtr
= BlockHdr
+ Offset
;
3419 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3423 case EFI_HII_SIBT_STRINGS_SCSU
:
3424 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3425 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3426 BlockSize
+= StringTextPtr
- BlockHdr
;
3428 for (Index
= 0; Index
< StringCount
; Index
++) {
3429 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3430 if (CurrentStringId
== StringId
) {
3431 *BlockType
= *BlockHdr
;
3432 *StringTextOffset
= StringTextPtr
- StringData
;
3435 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3440 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3443 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3446 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3447 BlockSize
+= StringTextPtr
- BlockHdr
;
3449 for (Index
= 0; Index
< StringCount
; Index
++) {
3450 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3451 if (CurrentStringId
== StringId
) {
3452 *BlockType
= *BlockHdr
;
3453 *StringTextOffset
= StringTextPtr
- StringData
;
3456 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3461 case EFI_HII_SIBT_STRING_UCS2
:
3462 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3463 StringTextPtr
= BlockHdr
+ Offset
;
3465 // Use StringSize to store the size of the specified string, including the NULL
3468 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3469 BlockSize
+= Offset
+ StringSize
;
3473 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3474 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3475 StringTextPtr
= BlockHdr
+ Offset
;
3477 // Use StrSize to store the size of the specified string, including the NULL
3480 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3481 BlockSize
+= Offset
+ StringSize
;
3485 case EFI_HII_SIBT_STRINGS_UCS2
:
3486 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3487 StringTextPtr
= BlockHdr
+ Offset
;
3488 BlockSize
+= Offset
;
3489 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3490 for (Index
= 0; Index
< StringCount
; Index
++) {
3491 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3492 BlockSize
+= StringSize
;
3493 if (CurrentStringId
== StringId
) {
3494 *BlockType
= *BlockHdr
;
3495 *StringTextOffset
= StringTextPtr
- StringData
;
3498 StringTextPtr
= StringTextPtr
+ StringSize
;
3503 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3504 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3505 StringTextPtr
= BlockHdr
+ Offset
;
3506 BlockSize
+= Offset
;
3509 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3512 for (Index
= 0; Index
< StringCount
; Index
++) {
3513 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3514 BlockSize
+= StringSize
;
3515 if (CurrentStringId
== StringId
) {
3516 *BlockType
= *BlockHdr
;
3517 *StringTextOffset
= StringTextPtr
- StringData
;
3520 StringTextPtr
= StringTextPtr
+ StringSize
;
3525 case EFI_HII_SIBT_DUPLICATE
:
3526 if (CurrentStringId
== StringId
) {
3528 // Incoming StringId is an id of a duplicate string block.
3529 // Update the StringId to be the previous string block.
3530 // Go back to the header of string block to search.
3534 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3535 sizeof (EFI_STRING_ID
)
3537 CurrentStringId
= 1;
3540 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3545 case EFI_HII_SIBT_SKIP1
:
3546 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3547 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3548 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3551 case EFI_HII_SIBT_SKIP2
:
3552 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3553 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3554 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3557 case EFI_HII_SIBT_EXT1
:
3560 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3563 BlockSize
+= Length8
;
3566 case EFI_HII_SIBT_EXT2
:
3567 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3568 BlockSize
+= Ext2
.Length
;
3571 case EFI_HII_SIBT_EXT4
:
3574 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3578 BlockSize
+= Length32
;
3585 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3586 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3587 *BlockType
= *BlockHdr
;
3589 if (StringId
== CurrentStringId
- 1) {
3591 // if only one skip item, return EFI_NOT_FOUND.
3593 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3594 return EFI_NOT_FOUND
;
3600 if (StringId
< CurrentStringId
- 1) {
3601 return EFI_NOT_FOUND
;
3604 BlockHdr
= StringData
+ BlockSize
;
3607 return EFI_NOT_FOUND
;
3611 CVfrStringDB::GetUnicodeStringTextSize (
3618 StringSize
= sizeof (CHAR16
);
3619 StringPtr
= (UINT16
*)StringSrc
;
3620 while (*StringPtr
++ != L
'\0') {
3621 StringSize
+= sizeof (CHAR16
);
3627 BOOLEAN VfrCompatibleMode
= FALSE
;
3629 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;