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 (
1518 SVfrVarStorageNode
*pNode
= NULL
;
1519 EFI_VARSTORE_ID VarStoreId
;
1521 if (StoreName
== NULL
) {
1522 return VFR_RETURN_FATAL_ERROR
;
1525 if (GetVarStoreId (StoreName
, &VarStoreId
) == VFR_RETURN_SUCCESS
) {
1526 return VFR_RETURN_REDEFINED
;
1529 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1530 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1531 return VFR_RETURN_UNDEFINED
;
1534 mNewVarStorageNode
= pNode
;
1536 return VFR_RETURN_SUCCESS
;
1540 CVfrDataStorage::NameTableAddItem (
1541 IN EFI_STRING_ID Item
1544 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1547 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1548 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1550 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1551 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1552 return VFR_RETURN_OUT_FOR_RESOURCES
;
1554 memcpy (NewTable
, OldTable
, TableSize
);
1555 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1558 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1559 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1561 return VFR_RETURN_SUCCESS
;
1565 CVfrDataStorage::DeclareNameVarStoreEnd (
1569 mNewVarStorageNode
->mGuid
= *Guid
;
1570 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1571 mNameVarStoreList
= mNewVarStorageNode
;
1573 mNewVarStorageNode
= NULL
;
1575 return VFR_RETURN_SUCCESS
;
1579 CVfrDataStorage::DeclareEfiVarStore (
1580 IN CHAR8
*StoreName
,
1582 IN EFI_STRING_ID NameStrId
,
1587 SVfrVarStorageNode
*pNode
;
1588 EFI_VARSTORE_ID VarStoreId
;
1590 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1591 return VFR_RETURN_FATAL_ERROR
;
1594 if (VarSize
> sizeof (UINT64
)) {
1595 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1598 if (GetVarStoreId (StoreName
, &VarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1599 return VFR_RETURN_REDEFINED
;
1602 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1603 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1604 return VFR_RETURN_OUT_FOR_RESOURCES
;
1607 pNode
->mNext
= mEfiVarStoreList
;
1608 mEfiVarStoreList
= pNode
;
1610 return VFR_RETURN_SUCCESS
;
1614 CVfrDataStorage::DeclareBufferVarStore (
1615 IN CHAR8
*StoreName
,
1617 IN CVfrVarDataTypeDB
*DataTypeDB
,
1619 IN EFI_VARSTORE_ID VarStoreId
,
1623 SVfrVarStorageNode
*pNew
= NULL
;
1624 SVfrDataType
*pDataType
= NULL
;
1625 EFI_VARSTORE_ID TempVarStoreId
;
1627 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1628 return VFR_RETURN_FATAL_ERROR
;
1631 if (GetVarStoreId (StoreName
, &TempVarStoreId
, Guid
) == VFR_RETURN_SUCCESS
) {
1632 return VFR_RETURN_REDEFINED
;
1635 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1637 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1638 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1640 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1641 return VFR_RETURN_VARSTOREID_REDEFINED
;
1643 MarkVarStoreIdUsed (VarStoreId
);
1646 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1647 return VFR_RETURN_OUT_FOR_RESOURCES
;
1650 pNew
->mNext
= mBufferVarStoreList
;
1651 mBufferVarStoreList
= pNew
;
1653 if (gCVfrBufferConfig
.Register(StoreName
, Guid
) != 0) {
1654 return VFR_RETURN_FATAL_ERROR
;
1657 return VFR_RETURN_SUCCESS
;
1661 CVfrDataStorage::GetVarStoreByDataType (
1662 IN CHAR8
*DataTypeName
,
1663 OUT SVfrVarStorageNode
**VarNode
,
1664 IN EFI_GUID
*VarGuid
1667 SVfrVarStorageNode
*pNode
;
1668 SVfrVarStorageNode
*MatchNode
;
1671 // Framework VFR uses Data type name as varstore name, so don't need check again.
1673 if (VfrCompatibleMode
) {
1674 return VFR_RETURN_UNDEFINED
;
1678 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1679 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) != 0) {
1683 if ((VarGuid
!= NULL
)) {
1684 if (memcmp (VarGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1686 return VFR_RETURN_SUCCESS
;
1689 if (MatchNode
== NULL
) {
1693 // More than one varstores referred the same data structures.
1695 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1700 if (MatchNode
== NULL
) {
1701 return VFR_RETURN_UNDEFINED
;
1704 *VarNode
= MatchNode
;
1705 return VFR_RETURN_SUCCESS
;
1709 CVfrDataStorage::CheckGuidField (
1710 IN SVfrVarStorageNode
*pNode
,
1711 IN EFI_GUID
*StoreGuid
,
1712 IN BOOLEAN
*HasFoundOne
,
1713 OUT EFI_VFR_RETURN_CODE
*ReturnCode
1716 if (StoreGuid
!= NULL
) {
1718 // If has guid info, compare the guid filed.
1720 if (memcmp (StoreGuid
, &pNode
->mGuid
, sizeof (EFI_GUID
)) == 0) {
1722 // Both name and guid are same, this this varstore.
1724 mCurrVarStorageNode
= pNode
;
1725 *ReturnCode
= VFR_RETURN_SUCCESS
;
1730 // Not has Guid field, check whether this name is the only one.
1734 // The name has conflict, return name redefined.
1736 *ReturnCode
= VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR
;
1740 *HasFoundOne
= TRUE
;
1741 mCurrVarStorageNode
= pNode
;
1748 Base on the input store name and guid to find the varstore id.
1750 If both name and guid are inputed, base on the name and guid to
1751 found the varstore. If only name inputed, base on the name to
1752 found the varstore and go on to check whether more than one varstore
1753 has the same name. If only has found one varstore, return this
1754 varstore; if more than one varstore has same name, return varstore
1755 name redefined error. If no varstore found by varstore name, call
1756 function GetVarStoreByDataType and use inputed varstore name as
1757 data type name to search.
1760 CVfrDataStorage::GetVarStoreId (
1761 IN CHAR8
*StoreName
,
1762 OUT EFI_VARSTORE_ID
*VarStoreId
,
1763 IN EFI_GUID
*StoreGuid
1766 EFI_VFR_RETURN_CODE ReturnCode
;
1767 SVfrVarStorageNode
*pNode
;
1768 BOOLEAN HasFoundOne
= FALSE
;
1770 mCurrVarStorageNode
= NULL
;
1772 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1773 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1774 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1775 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1781 for (pNode
= mEfiVarStoreList
; 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
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1791 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1792 if (CheckGuidField(pNode
, StoreGuid
, &HasFoundOne
, &ReturnCode
)) {
1793 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1800 *VarStoreId
= mCurrVarStorageNode
->mVarStoreId
;
1801 return VFR_RETURN_SUCCESS
;
1804 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1807 // Assume that Data strucutre name is used as StoreName, and check again.
1809 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
, StoreGuid
);
1810 if (pNode
!= NULL
) {
1811 mCurrVarStorageNode
= pNode
;
1812 *VarStoreId
= pNode
->mVarStoreId
;
1819 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1820 IN EFI_VARSTORE_ID VarStoreId
,
1821 OUT CHAR8
**DataTypeName
1824 SVfrVarStorageNode
*pNode
;
1826 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1827 return VFR_RETURN_FATAL_ERROR
;
1830 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1831 if (pNode
->mVarStoreId
== VarStoreId
) {
1832 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1833 return VFR_RETURN_SUCCESS
;
1837 return VFR_RETURN_UNDEFINED
;
1840 EFI_VFR_VARSTORE_TYPE
1841 CVfrDataStorage::GetVarStoreType (
1842 IN EFI_VARSTORE_ID VarStoreId
1845 SVfrVarStorageNode
*pNode
;
1846 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1848 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1850 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1851 return VarStoreType
;
1854 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1855 if (pNode
->mVarStoreId
== VarStoreId
) {
1856 VarStoreType
= pNode
->mVarStoreType
;
1857 return VarStoreType
;
1861 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1862 if (pNode
->mVarStoreId
== VarStoreId
) {
1863 VarStoreType
= pNode
->mVarStoreType
;
1864 return VarStoreType
;
1868 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1869 if (pNode
->mVarStoreId
== VarStoreId
) {
1870 VarStoreType
= pNode
->mVarStoreType
;
1871 return VarStoreType
;
1875 return VarStoreType
;
1879 CVfrDataStorage::GetVarStoreGuid (
1880 IN EFI_VARSTORE_ID VarStoreId
1883 SVfrVarStorageNode
*pNode
;
1888 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1892 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1893 if (pNode
->mVarStoreId
== VarStoreId
) {
1894 VarGuid
= &pNode
->mGuid
;
1899 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1900 if (pNode
->mVarStoreId
== VarStoreId
) {
1901 VarGuid
= &pNode
->mGuid
;
1906 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1907 if (pNode
->mVarStoreId
== VarStoreId
) {
1908 VarGuid
= &pNode
->mGuid
;
1917 CVfrDataStorage::GetVarStoreName (
1918 IN EFI_VARSTORE_ID VarStoreId
,
1919 OUT CHAR8
**VarStoreName
1922 SVfrVarStorageNode
*pNode
;
1924 if (VarStoreName
== NULL
) {
1925 return VFR_RETURN_FATAL_ERROR
;
1928 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1929 if (pNode
->mVarStoreId
== VarStoreId
) {
1930 *VarStoreName
= pNode
->mVarStoreName
;
1931 return VFR_RETURN_SUCCESS
;
1935 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1936 if (pNode
->mVarStoreId
== VarStoreId
) {
1937 *VarStoreName
= pNode
->mVarStoreName
;
1938 return VFR_RETURN_SUCCESS
;
1942 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1943 if (pNode
->mVarStoreId
== VarStoreId
) {
1944 *VarStoreName
= pNode
->mVarStoreName
;
1945 return VFR_RETURN_SUCCESS
;
1949 *VarStoreName
= NULL
;
1950 return VFR_RETURN_UNDEFINED
;
1954 CVfrDataStorage::GetEfiVarStoreInfo (
1955 IN OUT EFI_VARSTORE_INFO
*Info
1959 return VFR_RETURN_FATAL_ERROR
;
1962 if (mCurrVarStorageNode
== NULL
) {
1963 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1966 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1967 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1968 switch (Info
->mVarTotalSize
) {
1970 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1973 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1976 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1979 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1982 return VFR_RETURN_FATAL_ERROR
;
1985 return VFR_RETURN_SUCCESS
;
1989 CVfrDataStorage::GetNameVarStoreInfo (
1990 OUT EFI_VARSTORE_INFO
*Info
,
1995 return VFR_RETURN_FATAL_ERROR
;
1998 if (mCurrVarStorageNode
== NULL
) {
1999 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
2003 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2005 if (VfrCompatibleMode
) {
2007 return VFR_RETURN_ERROR_ARRARY_NUM
;
2012 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
2014 return VFR_RETURN_SUCCESS
;
2017 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2018 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
2020 IN EFI_STRING_ID DefaultStoreNameId
,
2024 mObjBinAddr
= ObjBinAddr
;
2026 if (RefName
!= NULL
) {
2027 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2028 strcpy (mRefName
, RefName
);
2034 mDefaultId
= DefaultId
;
2035 mDefaultStoreNameId
= DefaultStoreNameId
;
2038 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2042 if (mRefName
!= NULL
) {
2047 CVfrDefaultStore::CVfrDefaultStore (
2051 mDefaultStoreList
= NULL
;
2054 CVfrDefaultStore::~CVfrDefaultStore (
2058 SVfrDefaultStoreNode
*pTmp
= NULL
;
2060 while (mDefaultStoreList
!= NULL
) {
2061 pTmp
= mDefaultStoreList
;
2062 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2068 CVfrDefaultStore::RegisterDefaultStore (
2069 IN CHAR8
*ObjBinAddr
,
2071 IN EFI_STRING_ID DefaultStoreNameId
,
2075 SVfrDefaultStoreNode
*pNode
= NULL
;
2077 if (RefName
== NULL
) {
2078 return VFR_RETURN_FATAL_ERROR
;
2081 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2082 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2083 return VFR_RETURN_REDEFINED
;
2087 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2088 return VFR_RETURN_OUT_FOR_RESOURCES
;
2091 pNode
->mNext
= mDefaultStoreList
;
2092 mDefaultStoreList
= pNode
;
2094 return VFR_RETURN_SUCCESS
;
2098 * assign new reference name or new default store name id only if
2099 * the original is invalid
2102 CVfrDefaultStore::ReRegisterDefaultStoreById (
2103 IN UINT16 DefaultId
,
2105 IN EFI_STRING_ID DefaultStoreNameId
2108 SVfrDefaultStoreNode
*pNode
= NULL
;
2110 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2111 if (pNode
->mDefaultId
== DefaultId
) {
2116 if (pNode
== NULL
) {
2117 return VFR_RETURN_UNDEFINED
;
2119 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2120 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2121 if (pNode
->mObjBinAddr
!= NULL
) {
2122 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2125 return VFR_RETURN_REDEFINED
;
2128 if (RefName
!= NULL
) {
2129 delete pNode
->mRefName
;
2130 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2131 if (pNode
->mRefName
!= NULL
) {
2132 strcpy (pNode
->mRefName
, RefName
);
2137 return VFR_RETURN_SUCCESS
;
2141 CVfrDefaultStore::DefaultIdRegistered (
2145 SVfrDefaultStoreNode
*pNode
= NULL
;
2147 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2148 if (pNode
->mDefaultId
== DefaultId
) {
2157 CVfrDefaultStore::GetDefaultId (
2159 OUT UINT16
*DefaultId
2162 SVfrDefaultStoreNode
*pTmp
= NULL
;
2164 if (DefaultId
== NULL
) {
2165 return VFR_RETURN_FATAL_ERROR
;
2168 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2169 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2170 *DefaultId
= pTmp
->mDefaultId
;
2171 return VFR_RETURN_SUCCESS
;
2175 return VFR_RETURN_UNDEFINED
;
2179 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2180 IN EFI_VARSTORE_ID DefaultId
,
2181 IN EFI_VARSTORE_INFO
&Info
,
2182 IN CHAR8
*VarStoreName
,
2183 IN EFI_GUID
*VarStoreGuid
,
2185 IN EFI_IFR_TYPE_VALUE Value
2188 SVfrDefaultStoreNode
*pNode
= NULL
;
2189 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2190 INTN Returnvalue
= 0;
2192 if (VarStoreName
== NULL
) {
2193 return VFR_RETURN_FATAL_ERROR
;
2196 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2197 if (pNode
->mDefaultId
== DefaultId
) {
2202 if (pNode
== NULL
) {
2203 return VFR_RETURN_UNDEFINED
;
2206 gCVfrBufferConfig
.Open ();
2208 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2209 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
, VarStoreGuid
)) == 0) {
2210 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, VarStoreGuid
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2215 gCVfrBufferConfig
.Close ();
2217 return VFR_RETURN_SUCCESS
;
2220 gCVfrBufferConfig
.Close ();
2221 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2224 SVfrRuleNode::SVfrRuleNode (
2229 if (RuleName
!= NULL
) {
2230 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2231 strcpy (mRuleName
, RuleName
);
2240 SVfrRuleNode::~SVfrRuleNode (
2244 if (mRuleName
!= NULL
) {
2249 CVfrRulesDB::CVfrRulesDB ()
2252 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2255 CVfrRulesDB::~CVfrRulesDB ()
2257 SVfrRuleNode
*pNode
;
2259 while(mRuleList
!= NULL
) {
2261 mRuleList
= mRuleList
->mNext
;
2267 CVfrRulesDB::RegisterRule (
2273 if (RuleName
== NULL
) {
2277 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2283 pNew
->mNext
= mRuleList
;
2288 CVfrRulesDB::GetRuleId (
2292 SVfrRuleNode
*pNode
;
2294 if (RuleName
== NULL
) {
2295 return EFI_RULE_ID_INVALID
;
2298 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2299 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2300 return pNode
->mRuleId
;
2304 return EFI_RULE_ID_INVALID
;
2307 CVfrRulesDB gCVfrRulesDB
;
2309 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2313 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2314 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2315 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2316 mVarType
= EFI_IFR_TYPE_OTHER
;
2320 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2321 IN EFI_VARSTORE_INFO
&Info
2324 mVarStoreId
= Info
.mVarStoreId
;
2325 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2326 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2327 mVarType
= Info
.mVarType
;
2328 mVarTotalSize
= Info
.mVarTotalSize
;
2332 EFI_VARSTORE_INFO::operator == (
2333 IN EFI_VARSTORE_INFO
*Info
2336 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2337 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2338 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2339 (mVarType
== Info
->mVarType
) &&
2340 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2347 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2350 CVfrQuestionDB::GetFreeQuestionId (
2354 UINT32 Index
, Mask
, Offset
;
2356 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2357 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2362 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2363 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2364 mFreeQIdBitMap
[Index
] |= Mask
;
2365 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2369 return EFI_QUESTION_ID_INVALID
;
2373 CVfrQuestionDB::ChekQuestionIdFree (
2374 IN EFI_QUESTION_ID QId
2377 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2378 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2380 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2384 CVfrQuestionDB::MarkQuestionIdUsed (
2385 IN EFI_QUESTION_ID QId
2388 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2389 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2391 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2395 CVfrQuestionDB::MarkQuestionIdUnused (
2396 IN EFI_QUESTION_ID QId
2399 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2400 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2402 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2405 SVfrQuestionNode::SVfrQuestionNode (
2413 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2416 mQtype
= QUESTION_NORMAL
;
2419 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2420 strcpy (mName
, "$DEFAULT");
2422 mName
= new CHAR8
[strlen (Name
) + 1];
2423 strcpy (mName
, Name
);
2426 if (VarIdStr
!= NULL
) {
2427 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2428 strcpy (mVarIdStr
, VarIdStr
);
2430 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2431 strcpy (mVarIdStr
, "$");
2435 SVfrQuestionNode::~SVfrQuestionNode (
2439 if (mName
!= NULL
) {
2443 if (mVarIdStr
!= NULL
) {
2448 CVfrQuestionDB::CVfrQuestionDB ()
2452 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2453 mFreeQIdBitMap
[Index
] = 0;
2456 // Question ID 0 is reserved.
2457 mFreeQIdBitMap
[0] = 0x80000000;
2458 mQuestionList
= NULL
;
2461 CVfrQuestionDB::~CVfrQuestionDB ()
2463 SVfrQuestionNode
*pNode
;
2465 while (mQuestionList
!= NULL
) {
2466 pNode
= mQuestionList
;
2467 mQuestionList
= mQuestionList
->mNext
;
2473 // Reset to init state
2476 CVfrQuestionDB::ResetInit(
2481 SVfrQuestionNode
*pNode
;
2483 while (mQuestionList
!= NULL
) {
2484 pNode
= mQuestionList
;
2485 mQuestionList
= mQuestionList
->mNext
;
2489 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2490 mFreeQIdBitMap
[Index
] = 0;
2493 // Question ID 0 is reserved.
2494 mFreeQIdBitMap
[0] = 0x80000000;
2495 mQuestionList
= NULL
;
2499 CVfrQuestionDB::PrintAllQuestion (
2503 SVfrQuestionNode
*pNode
= NULL
;
2505 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2506 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2511 CVfrQuestionDB::RegisterQuestion (
2514 IN OUT EFI_QUESTION_ID
&QuestionId
2517 SVfrQuestionNode
*pNode
= NULL
;
2519 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2520 return VFR_RETURN_REDEFINED
;
2523 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2524 return VFR_RETURN_OUT_FOR_RESOURCES
;
2527 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2528 QuestionId
= GetFreeQuestionId ();
2531 // For Framework Vfr, don't check question ID conflict.
2533 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2535 return VFR_RETURN_QUESTIONID_REDEFINED
;
2537 MarkQuestionIdUsed (QuestionId
);
2539 pNode
->mQuestionId
= QuestionId
;
2541 pNode
->mNext
= mQuestionList
;
2542 mQuestionList
= pNode
;
2544 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2546 return VFR_RETURN_SUCCESS
;
2550 CVfrQuestionDB::RegisterOldDateQuestion (
2551 IN CHAR8
*YearVarId
,
2552 IN CHAR8
*MonthVarId
,
2554 IN OUT EFI_QUESTION_ID
&QuestionId
2557 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2560 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2564 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2567 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2570 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2574 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2575 QuestionId
= GetFreeQuestionId ();
2577 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2580 MarkQuestionIdUsed (QuestionId
);
2583 pNode
[0]->mQuestionId
= QuestionId
;
2584 pNode
[1]->mQuestionId
= QuestionId
;
2585 pNode
[2]->mQuestionId
= QuestionId
;
2586 pNode
[0]->mQtype
= QUESTION_DATE
;
2587 pNode
[1]->mQtype
= QUESTION_DATE
;
2588 pNode
[2]->mQtype
= QUESTION_DATE
;
2589 pNode
[0]->mNext
= pNode
[1];
2590 pNode
[1]->mNext
= pNode
[2];
2591 pNode
[2]->mNext
= mQuestionList
;
2592 mQuestionList
= pNode
[0];
2594 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2595 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2596 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2601 for (Index
= 0; Index
< 3; Index
++) {
2602 if (pNode
[Index
] != NULL
) {
2603 delete pNode
[Index
];
2606 QuestionId
= EFI_QUESTION_ID_INVALID
;
2610 CVfrQuestionDB::RegisterNewDateQuestion (
2612 IN CHAR8
*BaseVarId
,
2613 IN OUT EFI_QUESTION_ID
&QuestionId
2616 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2618 CHAR8
*VarIdStr
[3] = {NULL
, };
2621 if (BaseVarId
== NULL
&& Name
== NULL
) {
2625 if (BaseVarId
!= NULL
) {
2626 Len
= strlen (BaseVarId
);
2628 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2629 if (VarIdStr
[0] != NULL
) {
2630 strcpy (VarIdStr
[0], BaseVarId
);
2631 strcat (VarIdStr
[0], ".Year");
2633 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2634 if (VarIdStr
[1] != NULL
) {
2635 strcpy (VarIdStr
[1], BaseVarId
);
2636 strcat (VarIdStr
[1], ".Month");
2638 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2639 if (VarIdStr
[2] != NULL
) {
2640 strcpy (VarIdStr
[2], BaseVarId
);
2641 strcat (VarIdStr
[2], ".Day");
2644 Len
= strlen (Name
);
2646 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2647 if (VarIdStr
[0] != NULL
) {
2648 strcpy (VarIdStr
[0], Name
);
2649 strcat (VarIdStr
[0], ".Year");
2651 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2652 if (VarIdStr
[1] != NULL
) {
2653 strcpy (VarIdStr
[1], Name
);
2654 strcat (VarIdStr
[1], ".Month");
2656 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2657 if (VarIdStr
[2] != NULL
) {
2658 strcpy (VarIdStr
[2], Name
);
2659 strcat (VarIdStr
[2], ".Day");
2663 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2666 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2669 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2673 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2674 QuestionId
= GetFreeQuestionId ();
2676 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2679 MarkQuestionIdUsed (QuestionId
);
2682 pNode
[0]->mQuestionId
= QuestionId
;
2683 pNode
[1]->mQuestionId
= QuestionId
;
2684 pNode
[2]->mQuestionId
= QuestionId
;
2685 pNode
[0]->mQtype
= QUESTION_DATE
;
2686 pNode
[1]->mQtype
= QUESTION_DATE
;
2687 pNode
[2]->mQtype
= QUESTION_DATE
;
2688 pNode
[0]->mNext
= pNode
[1];
2689 pNode
[1]->mNext
= pNode
[2];
2690 pNode
[2]->mNext
= mQuestionList
;
2691 mQuestionList
= pNode
[0];
2693 for (Index
= 0; Index
< 3; Index
++) {
2694 if (VarIdStr
[Index
] != NULL
) {
2695 delete VarIdStr
[Index
];
2699 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2700 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2701 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2706 for (Index
= 0; Index
< 3; Index
++) {
2707 if (pNode
[Index
] != NULL
) {
2708 delete pNode
[Index
];
2711 if (VarIdStr
[Index
] != NULL
) {
2712 delete VarIdStr
[Index
];
2718 CVfrQuestionDB::RegisterOldTimeQuestion (
2719 IN CHAR8
*HourVarId
,
2720 IN CHAR8
*MinuteVarId
,
2721 IN CHAR8
*SecondVarId
,
2722 IN OUT EFI_QUESTION_ID
&QuestionId
2725 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2728 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2732 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2735 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2738 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2742 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2743 QuestionId
= GetFreeQuestionId ();
2745 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2748 MarkQuestionIdUsed (QuestionId
);
2751 pNode
[0]->mQuestionId
= QuestionId
;
2752 pNode
[1]->mQuestionId
= QuestionId
;
2753 pNode
[2]->mQuestionId
= QuestionId
;
2754 pNode
[0]->mQtype
= QUESTION_TIME
;
2755 pNode
[1]->mQtype
= QUESTION_TIME
;
2756 pNode
[2]->mQtype
= QUESTION_TIME
;
2757 pNode
[0]->mNext
= pNode
[1];
2758 pNode
[1]->mNext
= pNode
[2];
2759 pNode
[2]->mNext
= mQuestionList
;
2760 mQuestionList
= pNode
[0];
2762 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2763 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2764 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2769 for (Index
= 0; Index
< 3; Index
++) {
2770 if (pNode
[Index
] != NULL
) {
2771 delete pNode
[Index
];
2774 QuestionId
= EFI_QUESTION_ID_INVALID
;
2778 CVfrQuestionDB::RegisterNewTimeQuestion (
2780 IN CHAR8
*BaseVarId
,
2781 IN OUT EFI_QUESTION_ID
&QuestionId
2784 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2786 CHAR8
*VarIdStr
[3] = {NULL
, };
2789 if (BaseVarId
== NULL
&& Name
== NULL
) {
2793 if (BaseVarId
!= NULL
) {
2794 Len
= strlen (BaseVarId
);
2796 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2797 if (VarIdStr
[0] != NULL
) {
2798 strcpy (VarIdStr
[0], BaseVarId
);
2799 strcat (VarIdStr
[0], ".Hour");
2801 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2802 if (VarIdStr
[1] != NULL
) {
2803 strcpy (VarIdStr
[1], BaseVarId
);
2804 strcat (VarIdStr
[1], ".Minute");
2806 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2807 if (VarIdStr
[2] != NULL
) {
2808 strcpy (VarIdStr
[2], BaseVarId
);
2809 strcat (VarIdStr
[2], ".Second");
2812 Len
= strlen (Name
);
2814 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2815 if (VarIdStr
[0] != NULL
) {
2816 strcpy (VarIdStr
[0], Name
);
2817 strcat (VarIdStr
[0], ".Hour");
2819 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2820 if (VarIdStr
[1] != NULL
) {
2821 strcpy (VarIdStr
[1], Name
);
2822 strcat (VarIdStr
[1], ".Minute");
2824 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2825 if (VarIdStr
[2] != NULL
) {
2826 strcpy (VarIdStr
[2], Name
);
2827 strcat (VarIdStr
[2], ".Second");
2831 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2834 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2837 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2841 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2842 QuestionId
= GetFreeQuestionId ();
2844 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2847 MarkQuestionIdUsed (QuestionId
);
2850 pNode
[0]->mQuestionId
= QuestionId
;
2851 pNode
[1]->mQuestionId
= QuestionId
;
2852 pNode
[2]->mQuestionId
= QuestionId
;
2853 pNode
[0]->mQtype
= QUESTION_TIME
;
2854 pNode
[1]->mQtype
= QUESTION_TIME
;
2855 pNode
[2]->mQtype
= QUESTION_TIME
;
2856 pNode
[0]->mNext
= pNode
[1];
2857 pNode
[1]->mNext
= pNode
[2];
2858 pNode
[2]->mNext
= mQuestionList
;
2859 mQuestionList
= pNode
[0];
2861 for (Index
= 0; Index
< 3; Index
++) {
2862 if (VarIdStr
[Index
] != NULL
) {
2863 delete VarIdStr
[Index
];
2867 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2868 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2869 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2874 for (Index
= 0; Index
< 3; Index
++) {
2875 if (pNode
[Index
] != NULL
) {
2876 delete pNode
[Index
];
2879 if (VarIdStr
[Index
] != NULL
) {
2880 delete VarIdStr
[Index
];
2886 CVfrQuestionDB::RegisterRefQuestion (
2888 IN CHAR8
*BaseVarId
,
2889 IN OUT EFI_QUESTION_ID
&QuestionId
2892 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2894 CHAR8
*VarIdStr
[4] = {NULL
, };
2897 if (BaseVarId
== NULL
&& Name
== NULL
) {
2901 if (BaseVarId
!= NULL
) {
2902 Len
= strlen (BaseVarId
);
2904 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2905 if (VarIdStr
[0] != NULL
) {
2906 strcpy (VarIdStr
[0], BaseVarId
);
2907 strcat (VarIdStr
[0], ".QuestionId");
2909 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2910 if (VarIdStr
[1] != NULL
) {
2911 strcpy (VarIdStr
[1], BaseVarId
);
2912 strcat (VarIdStr
[1], ".FormId");
2914 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2915 if (VarIdStr
[2] != NULL
) {
2916 strcpy (VarIdStr
[2], BaseVarId
);
2917 strcat (VarIdStr
[2], ".FormSetGuid");
2919 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2920 if (VarIdStr
[3] != NULL
) {
2921 strcpy (VarIdStr
[3], BaseVarId
);
2922 strcat (VarIdStr
[3], ".DevicePath");
2925 Len
= strlen (Name
);
2927 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2928 if (VarIdStr
[0] != NULL
) {
2929 strcpy (VarIdStr
[0], Name
);
2930 strcat (VarIdStr
[0], ".QuestionId");
2932 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2933 if (VarIdStr
[1] != NULL
) {
2934 strcpy (VarIdStr
[1], Name
);
2935 strcat (VarIdStr
[1], ".FormId");
2937 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2938 if (VarIdStr
[2] != NULL
) {
2939 strcpy (VarIdStr
[2], Name
);
2940 strcat (VarIdStr
[2], ".FormSetGuid");
2942 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2943 if (VarIdStr
[3] != NULL
) {
2944 strcpy (VarIdStr
[3], Name
);
2945 strcat (VarIdStr
[3], ".DevicePath");
2949 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
2952 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
2955 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
2958 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
2962 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2963 QuestionId
= GetFreeQuestionId ();
2965 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2968 MarkQuestionIdUsed (QuestionId
);
2971 pNode
[0]->mQuestionId
= QuestionId
;
2972 pNode
[1]->mQuestionId
= QuestionId
;
2973 pNode
[2]->mQuestionId
= QuestionId
;
2974 pNode
[3]->mQuestionId
= QuestionId
;
2975 pNode
[0]->mQtype
= QUESTION_REF
;
2976 pNode
[1]->mQtype
= QUESTION_REF
;
2977 pNode
[2]->mQtype
= QUESTION_REF
;
2978 pNode
[3]->mQtype
= QUESTION_REF
;
2979 pNode
[0]->mNext
= pNode
[1];
2980 pNode
[1]->mNext
= pNode
[2];
2981 pNode
[2]->mNext
= pNode
[3];
2982 pNode
[3]->mNext
= mQuestionList
;
2983 mQuestionList
= pNode
[0];
2985 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2986 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2987 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2988 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2993 for (Index
= 0; Index
< 4; Index
++) {
2994 if (pNode
[Index
] != NULL
) {
2995 delete pNode
[Index
];
2998 if (VarIdStr
[Index
] != NULL
) {
2999 delete VarIdStr
[Index
];
3005 CVfrQuestionDB::UpdateQuestionId (
3006 IN EFI_QUESTION_ID QId
,
3007 IN EFI_QUESTION_ID NewQId
3010 SVfrQuestionNode
*pNode
= NULL
;
3012 if (QId
== NewQId
) {
3014 return VFR_RETURN_SUCCESS
;
3018 // For Framework Vfr, don't check question ID conflict.
3020 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
3021 return VFR_RETURN_REDEFINED
;
3024 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3025 if (pNode
->mQuestionId
== QId
) {
3030 if (pNode
== NULL
) {
3031 return VFR_RETURN_UNDEFINED
;
3034 MarkQuestionIdUnused (QId
);
3035 pNode
->mQuestionId
= NewQId
;
3036 MarkQuestionIdUsed (NewQId
);
3038 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
3040 return VFR_RETURN_SUCCESS
;
3044 CVfrQuestionDB::GetQuestionId (
3047 OUT EFI_QUESTION_ID
&QuestionId
,
3048 OUT UINT32
&BitMask
,
3049 OUT EFI_QUESION_TYPE
*QType
3052 SVfrQuestionNode
*pNode
;
3054 QuestionId
= EFI_QUESTION_ID_INVALID
;
3055 BitMask
= 0x00000000;
3056 if (QType
!= NULL
) {
3057 *QType
= QUESTION_NORMAL
;
3060 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
3064 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3066 if (strcmp (pNode
->mName
, Name
) != 0) {
3071 if (VarIdStr
!= NULL
) {
3072 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
3077 QuestionId
= pNode
->mQuestionId
;
3078 BitMask
= pNode
->mBitMask
;
3079 if (QType
!= NULL
) {
3080 *QType
= pNode
->mQtype
;
3089 CVfrQuestionDB::FindQuestion (
3090 IN EFI_QUESTION_ID QuestionId
3093 SVfrQuestionNode
*pNode
;
3095 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3096 return VFR_RETURN_INVALID_PARAMETER
;
3099 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3100 if (pNode
->mQuestionId
== QuestionId
) {
3101 return VFR_RETURN_SUCCESS
;
3105 return VFR_RETURN_UNDEFINED
;
3109 CVfrQuestionDB::FindQuestion (
3113 SVfrQuestionNode
*pNode
;
3116 return VFR_RETURN_FATAL_ERROR
;
3119 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3120 if (strcmp (pNode
->mName
, Name
) == 0) {
3121 return VFR_RETURN_SUCCESS
;
3125 return VFR_RETURN_UNDEFINED
;
3128 CVfrStringDB::CVfrStringDB ()
3130 mStringFileName
= NULL
;
3133 CVfrStringDB::~CVfrStringDB ()
3135 if (mStringFileName
!= NULL
) {
3136 delete mStringFileName
;
3138 mStringFileName
= NULL
;
3143 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3147 if (StringFileName
== NULL
) {
3151 FileLen
= strlen (StringFileName
) + 1;
3152 mStringFileName
= new CHAR8
[FileLen
];
3153 if (mStringFileName
== NULL
) {
3157 strcpy (mStringFileName
, StringFileName
);
3158 mStringFileName
[FileLen
- 1] = '\0';
3163 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3164 from a set of supported languages.
3166 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3167 contains a set of language codes.
3168 @param[in] Language A variable that contains pointers to Null-terminated
3169 ASCII strings that contain one language codes.
3171 @retval FALSE The best matching language could not be found in SupportedLanguages.
3172 @retval TRUE The best matching language could be found in SupportedLanguages.
3176 CVfrStringDB::GetBestLanguage (
3177 IN CONST CHAR8
*SupportedLanguages
,
3181 UINTN CompareLength
;
3182 UINTN LanguageLength
;
3183 CONST CHAR8
*Supported
;
3185 if (SupportedLanguages
== NULL
|| Language
== NULL
){
3190 // Determine the length of the first RFC 4646 language code in Language
3192 for (LanguageLength
= 0; Language
[LanguageLength
] != 0 && Language
[LanguageLength
] != ';'; LanguageLength
++);
3195 // Trim back the length of Language used until it is empty
3197 while (LanguageLength
> 0) {
3199 // Loop through all language codes in SupportedLanguages
3201 for (Supported
= SupportedLanguages
; *Supported
!= '\0'; Supported
+= CompareLength
) {
3203 // Skip ';' characters in Supported
3205 for (; *Supported
!= '\0' && *Supported
== ';'; Supported
++);
3207 // Determine the length of the next language code in Supported
3209 for (CompareLength
= 0; Supported
[CompareLength
] != 0 && Supported
[CompareLength
] != ';'; CompareLength
++);
3211 // If Language is longer than the Supported, then skip to the next language
3213 if (LanguageLength
> CompareLength
) {
3218 // See if the first LanguageLength characters in Supported match Language
3220 if (strncmp (Supported
, Language
, LanguageLength
) == 0) {
3226 // Trim Language from the right to the next '-' character
3228 for (LanguageLength
--; LanguageLength
> 0 && Language
[LanguageLength
] != '-'; LanguageLength
--);
3232 // No matches were found
3239 CVfrStringDB::GetVarStoreNameFormStringId (
3240 IN EFI_STRING_ID StringId
3243 FILE *pInFile
= NULL
;
3248 CHAR16
*UnicodeString
;
3249 CHAR8
*VarStoreName
= NULL
;
3253 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3255 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3257 if (mStringFileName
== '\0' ) {
3261 if ((pInFile
= fopen (mStringFileName
, "rb")) == NULL
) {
3268 fseek (pInFile
, 0, SEEK_END
);
3269 Length
= ftell (pInFile
);
3270 fseek (pInFile
, 0, SEEK_SET
);
3275 StringPtr
= new UINT8
[Length
];
3276 if (StringPtr
== NULL
) {
3280 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3283 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3285 // Check the String package.
3287 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3293 // Search the language, get best language base on RFC 4647 matching algorithm.
3295 Current
= StringPtr
;
3296 while (!GetBestLanguage ("en", PkgHeader
->Language
)) {
3297 Current
+= PkgHeader
->Header
.Length
;
3298 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3300 // If can't find string package base on language, just return the first string package.
3302 if (Current
- StringPtr
>= Length
) {
3303 Current
= StringPtr
;
3304 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3309 Current
+= PkgHeader
->HdrSize
;
3311 // Find the string block according the stringId.
3313 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3314 if (Status
!= EFI_SUCCESS
) {
3320 // Get varstore name according the string type.
3322 switch (BlockType
) {
3323 case EFI_HII_SIBT_STRING_SCSU
:
3324 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3325 case EFI_HII_SIBT_STRINGS_SCSU
:
3326 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3327 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3328 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3329 strcpy (VarStoreName
, StringName
);
3331 case EFI_HII_SIBT_STRING_UCS2
:
3332 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3333 case EFI_HII_SIBT_STRINGS_UCS2
:
3334 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3335 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3336 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3337 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3338 VarStoreName
= DestTmp
;
3339 while (*UnicodeString
!= '\0') {
3340 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3350 return VarStoreName
;
3354 CVfrStringDB::FindStringBlock (
3355 IN UINT8
*StringData
,
3356 IN EFI_STRING_ID StringId
,
3357 OUT UINT32
*StringTextOffset
,
3358 OUT UINT8
*BlockType
3362 EFI_STRING_ID CurrentStringId
;
3365 UINT8
*StringTextPtr
;
3370 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3374 CurrentStringId
= 1;
3377 // Parse the string blocks to get the string text and font.
3379 BlockHdr
= StringData
;
3382 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3383 switch (*BlockHdr
) {
3384 case EFI_HII_SIBT_STRING_SCSU
:
3385 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3386 StringTextPtr
= BlockHdr
+ Offset
;
3387 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3391 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3392 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3393 StringTextPtr
= BlockHdr
+ Offset
;
3394 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3398 case EFI_HII_SIBT_STRINGS_SCSU
:
3399 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3400 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3401 BlockSize
+= StringTextPtr
- BlockHdr
;
3403 for (Index
= 0; Index
< StringCount
; Index
++) {
3404 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3405 if (CurrentStringId
== StringId
) {
3406 *BlockType
= *BlockHdr
;
3407 *StringTextOffset
= StringTextPtr
- StringData
;
3410 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3415 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3418 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3421 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3422 BlockSize
+= StringTextPtr
- BlockHdr
;
3424 for (Index
= 0; Index
< StringCount
; Index
++) {
3425 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3426 if (CurrentStringId
== StringId
) {
3427 *BlockType
= *BlockHdr
;
3428 *StringTextOffset
= StringTextPtr
- StringData
;
3431 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3436 case EFI_HII_SIBT_STRING_UCS2
:
3437 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3438 StringTextPtr
= BlockHdr
+ Offset
;
3440 // Use StringSize to store the size of the specified string, including the NULL
3443 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3444 BlockSize
+= Offset
+ StringSize
;
3448 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3449 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3450 StringTextPtr
= BlockHdr
+ Offset
;
3452 // Use StrSize to store the size of the specified string, including the NULL
3455 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3456 BlockSize
+= Offset
+ StringSize
;
3460 case EFI_HII_SIBT_STRINGS_UCS2
:
3461 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3462 StringTextPtr
= BlockHdr
+ Offset
;
3463 BlockSize
+= Offset
;
3464 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3465 for (Index
= 0; Index
< StringCount
; Index
++) {
3466 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3467 BlockSize
+= StringSize
;
3468 if (CurrentStringId
== StringId
) {
3469 *BlockType
= *BlockHdr
;
3470 *StringTextOffset
= StringTextPtr
- StringData
;
3473 StringTextPtr
= StringTextPtr
+ StringSize
;
3478 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3479 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3480 StringTextPtr
= BlockHdr
+ Offset
;
3481 BlockSize
+= Offset
;
3484 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3487 for (Index
= 0; Index
< StringCount
; Index
++) {
3488 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3489 BlockSize
+= StringSize
;
3490 if (CurrentStringId
== StringId
) {
3491 *BlockType
= *BlockHdr
;
3492 *StringTextOffset
= StringTextPtr
- StringData
;
3495 StringTextPtr
= StringTextPtr
+ StringSize
;
3500 case EFI_HII_SIBT_DUPLICATE
:
3501 if (CurrentStringId
== StringId
) {
3503 // Incoming StringId is an id of a duplicate string block.
3504 // Update the StringId to be the previous string block.
3505 // Go back to the header of string block to search.
3509 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3510 sizeof (EFI_STRING_ID
)
3512 CurrentStringId
= 1;
3515 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3520 case EFI_HII_SIBT_SKIP1
:
3521 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3522 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3523 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3526 case EFI_HII_SIBT_SKIP2
:
3527 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3528 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3529 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3532 case EFI_HII_SIBT_EXT1
:
3535 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3538 BlockSize
+= Length8
;
3541 case EFI_HII_SIBT_EXT2
:
3542 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3543 BlockSize
+= Ext2
.Length
;
3546 case EFI_HII_SIBT_EXT4
:
3549 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3553 BlockSize
+= Length32
;
3560 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3561 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3562 *BlockType
= *BlockHdr
;
3564 if (StringId
== CurrentStringId
- 1) {
3566 // if only one skip item, return EFI_NOT_FOUND.
3568 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3569 return EFI_NOT_FOUND
;
3575 if (StringId
< CurrentStringId
- 1) {
3576 return EFI_NOT_FOUND
;
3579 BlockHdr
= StringData
+ BlockSize
;
3582 return EFI_NOT_FOUND
;
3586 CVfrStringDB::GetUnicodeStringTextSize (
3593 StringSize
= sizeof (CHAR16
);
3594 StringPtr
= (UINT16
*)StringSrc
;
3595 while (*StringPtr
++ != L
'\0') {
3596 StringSize
+= sizeof (CHAR16
);
3602 BOOLEAN VfrCompatibleMode
= FALSE
;
3604 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;