3 Vfr common library functions.
5 Copyright (c) 2004 - 2011, 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 (
135 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
136 strcpy (mName
, Name
);
141 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
147 SConfigItem::SConfigItem (
153 IN EFI_IFR_TYPE_VALUE Value
162 if ((mName
= new CHAR8
[strlen (Name
) + 1]) != NULL
) {
163 strcpy (mName
, Name
);
168 if ((mId
= new CHAR8
[strlen (Id
) + 1]) != NULL
) {
173 mInfoStrList
= new SConfigInfo(Type
, Offset
, Width
, Value
);
176 SConfigItem::~SConfigItem (
182 BUFFER_SAFE_FREE (mName
);
183 BUFFER_SAFE_FREE (mId
);
184 while (mInfoStrList
!= NULL
) {
186 mInfoStrList
= mInfoStrList
->mNext
;
188 BUFFER_SAFE_FREE (Info
);
193 CVfrBufferConfig::Register (
200 if (Select (Name
) == 0) {
204 if ((pNew
= new SConfigItem (Name
, Id
)) == NULL
) {
207 if (mItemListHead
== NULL
) {
208 mItemListHead
= pNew
;
209 mItemListTail
= pNew
;
211 mItemListTail
->mNext
= pNew
;
212 mItemListTail
= pNew
;
220 CVfrBufferConfig::Open (
224 mItemListPos
= mItemListHead
;
228 CVfrBufferConfig::Eof(
232 return (mItemListPos
== NULL
) ? TRUE
: FALSE
;
236 CVfrBufferConfig::Select (
244 mItemListPos
= mItemListHead
;
247 for (p
= mItemListHead
; p
!= NULL
; p
= p
->mNext
) {
248 if (strcmp (p
->mName
, Name
) != 0) {
253 if (p
->mId
== NULL
|| strcmp (p
->mId
, Id
) != 0) {
256 } else if (p
->mId
!= NULL
) {
269 CVfrBufferConfig::Write (
276 IN EFI_IFR_TYPE_VALUE Value
283 if ((Ret
= Select (Name
)) != 0) {
289 if (Select (Name
, Id
) != 0) {
290 if ((pItem
= new SConfigItem (Name
, Id
, Type
, Offset
, (UINT16
) Width
, Value
)) == NULL
) {
293 if (mItemListHead
== NULL
) {
294 mItemListHead
= pItem
;
295 mItemListTail
= pItem
;
297 mItemListTail
->mNext
= pItem
;
298 mItemListTail
= pItem
;
300 mItemListPos
= pItem
;
302 // tranverse the list to find out if there's already the value for the same offset
303 for (pInfo
= mItemListPos
->mInfoStrList
; pInfo
!= NULL
; pInfo
= pInfo
->mNext
) {
304 if (pInfo
->mOffset
== Offset
) {
305 // check if the value and width are the same; return error if not
306 if ((Id
!= NULL
) && (pInfo
->mWidth
!= Width
|| memcmp(pInfo
->mValue
, &Value
, Width
) != 0)) {
307 return VFR_RETURN_DEFAULT_VALUE_REDEFINED
;
312 if((pInfo
= new SConfigInfo (Type
, Offset
, Width
, Value
)) == NULL
) {
315 pInfo
->mNext
= mItemListPos
->mInfoStrList
;
316 mItemListPos
->mInfoStrList
= pInfo
;
321 if (mItemListHead
== mItemListPos
) {
322 mItemListHead
= mItemListPos
->mNext
;
327 for (pItem
= mItemListHead
; pItem
->mNext
!= mItemListPos
; pItem
= pItem
->mNext
)
330 pItem
->mNext
= mItemListPos
->mNext
;
331 if (mItemListTail
== mItemListPos
) {
332 mItemListTail
= pItem
;
335 mItemListPos
= pItem
->mNext
;
338 case 'i' : // set info
339 if (mItemListPos
->mId
!= NULL
) {
340 delete mItemListPos
->mId
;
342 mItemListPos
->mId
= NULL
;
344 if ((mItemListPos
->mId
= new CHAR8
[strlen (Id
) + 1]) == NULL
) {
347 strcpy (mItemListPos
->mId
, Id
);
360 CVfrBufferConfig::Close (
367 #define BYTES_PRE_LINE 0x10
370 CVfrBufferConfig::OutputCFile (
375 CVfrBinaryOutput Output
;
384 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
385 if (Item
->mId
!= NULL
|| Item
->mInfoStrList
== NULL
) {
388 fprintf (pFile
, "\nunsigned char %s%sBlockName[] = {", BaseName
, Item
->mName
);
390 TotalLen
= sizeof (UINT32
);
391 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
392 TotalLen
+= sizeof (UINT16
) * 2;
394 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
396 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
397 fprintf (pFile
, "\n");
398 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
399 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
401 fprintf (pFile
, "\n};\n");
404 for (Item
= mItemListHead
; Item
!= NULL
; Item
= Item
->mNext
) {
405 if (Item
->mId
!= NULL
&& Item
->mInfoStrList
!= NULL
) {
406 fprintf (pFile
, "\nunsigned char %s%sDefault%s[] = {", BaseName
, Item
->mName
, Item
->mId
);
408 TotalLen
= sizeof (UINT32
);
409 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
410 TotalLen
+= Info
->mWidth
+ sizeof (UINT16
) * 2;
412 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&TotalLen
, sizeof (UINT32
));
414 for (Info
= Item
->mInfoStrList
; Info
!= NULL
; Info
= Info
->mNext
) {
415 fprintf (pFile
, "\n");
416 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mOffset
, sizeof (UINT16
));
417 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&Info
->mWidth
, sizeof (UINT16
));
418 if (Info
->mNext
== NULL
) {
419 Output
.WriteEnd (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
421 Output
.WriteLine (pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)Info
->mValue
, Info
->mWidth
);
424 fprintf (pFile
, "\n};\n");
429 CVfrBufferConfig::CVfrBufferConfig (
433 mItemListHead
= NULL
;
434 mItemListTail
= NULL
;
438 CVfrBufferConfig::~CVfrBufferConfig (
444 while (mItemListHead
!= NULL
) {
446 mItemListHead
= mItemListHead
->mNext
;
450 mItemListHead
= NULL
;
451 mItemListTail
= NULL
;
455 CVfrBufferConfig gCVfrBufferConfig
;
458 CONST CHAR8
*mTypeName
;
462 } gInternalTypesTable
[] = {
463 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64
, sizeof (UINT64
), sizeof (UINT64
)},
464 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32
, sizeof (UINT32
), sizeof (UINT32
)},
465 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16
, sizeof (UINT16
), sizeof (UINT16
)},
466 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8
, sizeof (UINT8
), sizeof (UINT8
)},
467 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN
, sizeof (BOOLEAN
), sizeof (BOOLEAN
)},
468 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE
, sizeof (EFI_HII_DATE
), sizeof (UINT16
)},
469 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING
, sizeof (EFI_STRING_ID
),sizeof (EFI_STRING_ID
)},
470 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME
, sizeof (EFI_HII_TIME
), sizeof (UINT8
)},
471 {"EFI_HII_REF", EFI_IFR_TYPE_REF
, sizeof (EFI_HII_REF
), sizeof (EFI_GUID
)},
472 {NULL
, EFI_IFR_TYPE_OTHER
, 0, 0}
483 if (TypeName
== NULL
) {
487 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
488 if (strcmp (TypeName
, gInternalTypesTable
[Index
].mTypeName
) == 0) {
505 while (*Str
&& *Str
== ' ') {
508 while (*Str
&& *Str
== '0') {
511 if (*Str
&& (*Str
== 'x' || *Str
== 'X')) {
528 Str
= TrimHex (Str
, &IsHex
);
529 for (Value
= 0; (c
= *Str
) != '\0'; Str
++) {
531 // BUG: does not handle overflow here
533 (IsHex
== TRUE
) ? (Value
<<= 4) : (Value
*= 10);
535 if ((IsHex
== TRUE
) && (c
>= 'a') && (c
<= 'f')) {
536 Value
+= (c
- 'a' + 10);
538 if ((IsHex
== TRUE
) && (c
>= 'A') && (c
<= 'F')) {
539 Value
+= (c
- 'A' + 10);
541 if (c
>= '0' && c
<= '9') {
550 CVfrVarDataTypeDB::RegisterNewType (
554 New
->mNext
= mDataTypeList
;
559 CVfrVarDataTypeDB::ExtractStructTypeName (
565 return VFR_RETURN_FATAL_ERROR
;
568 while((*VarStr
!= '\0') && (*VarStr
!= '.')) {
574 if (*VarStr
== '.') {
578 return VFR_RETURN_SUCCESS
;
582 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
589 CHAR8 ArrayStr
[MAX_NAME_LEN
+ 1];
591 ArrayIdx
= INVALID_ARRAY_INDEX
;
594 return VFR_RETURN_FATAL_ERROR
;
597 while((*VarStr
!= '\0') &&
611 return VFR_RETURN_SUCCESS
;
614 for (Idx
= 0; (Idx
< MAX_NAME_LEN
) && (*VarStr
!= '\0') && (*VarStr
!= ']'); VarStr
++, Idx
++) {
615 ArrayStr
[Idx
] = *VarStr
;
617 ArrayStr
[Idx
] = '\0';
619 if ((*VarStr
!= ']') && (ArrayStr
[0] == '\0')) {
620 return VFR_RETURN_DATA_STRING_ERROR
;
622 ArrayIdx
= _STR2U32 (ArrayStr
);
623 if (*VarStr
== ']') {
626 if (*VarStr
== '.') {
629 return VFR_RETURN_SUCCESS
;
631 return VFR_RETURN_DATA_STRING_ERROR
;
634 return VFR_RETURN_SUCCESS
;
638 CVfrVarDataTypeDB::GetTypeField (
639 IN CONST CHAR8
*FName
,
640 IN SVfrDataType
*Type
,
641 OUT SVfrDataField
*&Field
644 SVfrDataField
*pField
= NULL
;
646 if ((FName
== NULL
) && (Type
== NULL
)) {
647 return VFR_RETURN_FATAL_ERROR
;
650 for (pField
= Type
->mMembers
; pField
!= NULL
; pField
= pField
->mNext
) {
652 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
653 // add code to adjust it.
655 if (Type
->mType
== EFI_IFR_TYPE_TIME
) {
656 if (strcmp (FName
, "Hour") == 0) {
658 } else if (strcmp (FName
, "Minute") == 0) {
660 } else if (strcmp (FName
, "Second") == 0) {
665 if (strcmp (pField
->mFieldName
, FName
) == 0) {
667 return VFR_RETURN_SUCCESS
;
671 return VFR_RETURN_UNDEFINED
;
675 CVfrVarDataTypeDB::GetFieldOffset (
676 IN SVfrDataField
*Field
,
682 return VFR_RETURN_FATAL_ERROR
;
686 // Framework Vfr file Array Index is from 1.
687 // But Uefi Vfr file Array Index is from 0.
689 if (VfrCompatibleMode
&& ArrayIdx
!= INVALID_ARRAY_INDEX
) {
691 return VFR_RETURN_ERROR_ARRARY_NUM
;
693 ArrayIdx
= ArrayIdx
- 1;
696 if ((ArrayIdx
!= INVALID_ARRAY_INDEX
) && ((Field
->mArrayNum
== 0) || (Field
->mArrayNum
<= ArrayIdx
))) {
697 return VFR_RETURN_ERROR_ARRARY_NUM
;
701 // Be compatible with the current usage
702 // If ArraryIdx is not specified, the first one is used.
704 // if ArrayNum is larger than zero, ArraryIdx must be specified.
706 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
707 // return VFR_RETURN_ERROR_ARRARY_NUM;
711 Offset
= Field
->mOffset
+ Field
->mFieldType
->mTotalSize
* ((ArrayIdx
== INVALID_ARRAY_INDEX
) ? 0 : ArrayIdx
);
712 return VFR_RETURN_SUCCESS
;
716 CVfrVarDataTypeDB::GetFieldWidth (
717 IN SVfrDataField
*Field
724 return Field
->mFieldType
->mType
;
728 CVfrVarDataTypeDB::GetFieldSize (
729 IN SVfrDataField
*Field
,
734 return VFR_RETURN_FATAL_ERROR
;
737 if ((ArrayIdx
== INVALID_ARRAY_INDEX
) && (Field
->mArrayNum
!= 0)) {
738 return Field
->mFieldType
->mTotalSize
* Field
->mArrayNum
;
740 return Field
->mFieldType
->mTotalSize
;
745 CVfrVarDataTypeDB::InternalTypesListInit (
749 SVfrDataType
*New
= NULL
;
752 for (Index
= 0; gInternalTypesTable
[Index
].mTypeName
!= NULL
; Index
++) {
753 New
= new SVfrDataType
;
755 strcpy (New
->mTypeName
, gInternalTypesTable
[Index
].mTypeName
);
756 New
->mType
= gInternalTypesTable
[Index
].mType
;
757 New
->mAlign
= gInternalTypesTable
[Index
].mAlign
;
758 New
->mTotalSize
= gInternalTypesTable
[Index
].mSize
;
759 if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_DATE") == 0) {
760 SVfrDataField
*pYearField
= new SVfrDataField
;
761 SVfrDataField
*pMonthField
= new SVfrDataField
;
762 SVfrDataField
*pDayField
= new SVfrDataField
;
764 strcpy (pYearField
->mFieldName
, "Year");
765 GetDataType ((CHAR8
*)"UINT16", &pYearField
->mFieldType
);
766 pYearField
->mOffset
= 0;
767 pYearField
->mNext
= pMonthField
;
768 pYearField
->mArrayNum
= 0;
770 strcpy (pMonthField
->mFieldName
, "Month");
771 GetDataType ((CHAR8
*)"UINT8", &pMonthField
->mFieldType
);
772 pMonthField
->mOffset
= 2;
773 pMonthField
->mNext
= pDayField
;
774 pMonthField
->mArrayNum
= 0;
776 strcpy (pDayField
->mFieldName
, "Day");
777 GetDataType ((CHAR8
*)"UINT8", &pDayField
->mFieldType
);
778 pDayField
->mOffset
= 3;
779 pDayField
->mNext
= NULL
;
780 pDayField
->mArrayNum
= 0;
782 New
->mMembers
= pYearField
;
783 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_TIME") == 0) {
784 SVfrDataField
*pHoursField
= new SVfrDataField
;
785 SVfrDataField
*pMinutesField
= new SVfrDataField
;
786 SVfrDataField
*pSecondsField
= new SVfrDataField
;
788 strcpy (pHoursField
->mFieldName
, "Hours");
789 GetDataType ((CHAR8
*)"UINT8", &pHoursField
->mFieldType
);
790 pHoursField
->mOffset
= 0;
791 pHoursField
->mNext
= pMinutesField
;
792 pHoursField
->mArrayNum
= 0;
794 strcpy (pMinutesField
->mFieldName
, "Minutes");
795 GetDataType ((CHAR8
*)"UINT8", &pMinutesField
->mFieldType
);
796 pMinutesField
->mOffset
= 1;
797 pMinutesField
->mNext
= pSecondsField
;
798 pMinutesField
->mArrayNum
= 0;
800 strcpy (pSecondsField
->mFieldName
, "Seconds");
801 GetDataType ((CHAR8
*)"UINT8", &pSecondsField
->mFieldType
);
802 pSecondsField
->mOffset
= 2;
803 pSecondsField
->mNext
= NULL
;
804 pSecondsField
->mArrayNum
= 0;
806 New
->mMembers
= pHoursField
;
807 } else if (strcmp (gInternalTypesTable
[Index
].mTypeName
, "EFI_HII_REF") == 0) {
808 SVfrDataField
*pQuestionIdField
= new SVfrDataField
;
809 SVfrDataField
*pFormIdField
= new SVfrDataField
;
810 SVfrDataField
*pFormSetGuidField
= new SVfrDataField
;
811 SVfrDataField
*pDevicePathField
= new SVfrDataField
;
813 strcpy (pQuestionIdField
->mFieldName
, "QuestionId");
814 GetDataType ((CHAR8
*)"UINT16", &pQuestionIdField
->mFieldType
);
815 pQuestionIdField
->mOffset
= 0;
816 pQuestionIdField
->mNext
= pFormIdField
;
817 pQuestionIdField
->mArrayNum
= 0;
819 strcpy (pFormIdField
->mFieldName
, "FormId");
820 GetDataType ((CHAR8
*)"UINT16", &pFormIdField
->mFieldType
);
821 pFormIdField
->mOffset
= 2;
822 pFormIdField
->mNext
= pFormSetGuidField
;
823 pFormIdField
->mArrayNum
= 0;
825 strcpy (pFormSetGuidField
->mFieldName
, "FormSetGuid");
826 GetDataType ((CHAR8
*)"EFI_GUID", &pFormSetGuidField
->mFieldType
);
827 pFormSetGuidField
->mOffset
= 4;
828 pFormSetGuidField
->mNext
= pDevicePathField
;
829 pFormSetGuidField
->mArrayNum
= 0;
831 strcpy (pDevicePathField
->mFieldName
, "DevicePath");
832 GetDataType ((CHAR8
*)"EFI_STRING_ID", &pDevicePathField
->mFieldType
);
833 pDevicePathField
->mOffset
= 20;
834 pDevicePathField
->mNext
= NULL
;
835 pDevicePathField
->mArrayNum
= 0;
837 New
->mMembers
= pQuestionIdField
;
839 New
->mMembers
= NULL
;
842 RegisterNewType (New
);
848 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
852 mDataTypeList
= NULL
;
854 mCurrDataField
= NULL
;
855 mPackAlign
= DEFAULT_PACK_ALIGN
;
857 mFirstNewDataTypeName
= NULL
;
859 InternalTypesListInit ();
862 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
867 SVfrDataField
*pField
;
868 SVfrPackStackNode
*pPack
;
870 if (mNewDataType
!= NULL
) {
874 while (mDataTypeList
!= NULL
) {
875 pType
= mDataTypeList
;
876 mDataTypeList
= mDataTypeList
->mNext
;
877 while(pType
->mMembers
!= NULL
) {
878 pField
= pType
->mMembers
;
879 pType
->mMembers
= pType
->mMembers
->mNext
;
885 while (mPackStack
!= NULL
) {
887 mPackStack
= mPackStack
->mNext
;
893 CVfrVarDataTypeDB::Pack (
896 IN CHAR8
*Identifier
,
901 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
903 if (Action
& VFR_PACK_SHOW
) {
904 sprintf (Msg
, "value of pragma pack(show) == %d", mPackAlign
);
905 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Warning", Msg
);
908 if (Action
& VFR_PACK_PUSH
) {
909 SVfrPackStackNode
*pNew
= NULL
;
911 if ((pNew
= new SVfrPackStackNode (Identifier
, mPackAlign
)) == NULL
) {
912 return VFR_RETURN_FATAL_ERROR
;
914 pNew
->mNext
= mPackStack
;
918 if (Action
& VFR_PACK_POP
) {
919 SVfrPackStackNode
*pNode
= NULL
;
921 if (mPackStack
== NULL
) {
922 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "#pragma pack(pop...) : more pops than pushes");
925 for (pNode
= mPackStack
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
926 if (pNode
->Match (Identifier
) == TRUE
) {
927 mPackAlign
= pNode
->mNumber
;
928 mPackStack
= pNode
->mNext
;
933 if (Action
& VFR_PACK_ASSIGN
) {
934 PackAlign
= (Number
> 1) ? Number
+ Number
% 2 : Number
;
935 if ((PackAlign
== 0) || (PackAlign
> 16)) {
936 gCVfrErrorHandle
.PrintMsg (LineNum
, NULL
, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
938 mPackAlign
= PackAlign
;
942 return VFR_RETURN_SUCCESS
;
946 CVfrVarDataTypeDB::DeclareDataTypeBegin (
950 SVfrDataType
*pNewType
= NULL
;
952 pNewType
= new SVfrDataType
;
953 pNewType
->mTypeName
[0] = '\0';
954 pNewType
->mType
= EFI_IFR_TYPE_OTHER
;
955 pNewType
->mAlign
= DEFAULT_ALIGN
;
956 pNewType
->mTotalSize
= 0;
957 pNewType
->mMembers
= NULL
;
958 pNewType
->mNext
= NULL
;
960 mNewDataType
= pNewType
;
964 CVfrVarDataTypeDB::SetNewTypeName (
970 if (mNewDataType
== NULL
) {
971 return VFR_RETURN_ERROR_SKIPED
;
973 if (TypeName
== NULL
) {
974 return VFR_RETURN_FATAL_ERROR
;
976 if (strlen(TypeName
) >= MAX_NAME_LEN
) {
977 return VFR_RETURN_INVALID_PARAMETER
;
980 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
981 if (strcmp(pType
->mTypeName
, TypeName
) == 0) {
982 return VFR_RETURN_REDEFINED
;
986 strcpy(mNewDataType
->mTypeName
, TypeName
);
987 return VFR_RETURN_SUCCESS
;
991 CVfrVarDataTypeDB::DataTypeAddField (
997 SVfrDataField
*pNewField
= NULL
;
998 SVfrDataType
*pFieldType
= NULL
;
1002 CHECK_ERROR_RETURN (GetDataType (TypeName
, &pFieldType
), VFR_RETURN_SUCCESS
);
1004 if (strlen (FieldName
) >= MAX_NAME_LEN
) {
1005 return VFR_RETURN_INVALID_PARAMETER
;
1008 for (pTmp
= mNewDataType
->mMembers
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
1009 if (strcmp (pTmp
->mFieldName
, FieldName
) == 0) {
1010 return VFR_RETURN_REDEFINED
;
1014 Align
= MIN (mPackAlign
, pFieldType
->mAlign
);
1016 if ((pNewField
= new SVfrDataField
) == NULL
) {
1017 return VFR_RETURN_OUT_FOR_RESOURCES
;
1019 strcpy (pNewField
->mFieldName
, FieldName
);
1020 pNewField
->mFieldType
= pFieldType
;
1021 pNewField
->mArrayNum
= ArrayNum
;
1022 if ((mNewDataType
->mTotalSize
% Align
) == 0) {
1023 pNewField
->mOffset
= mNewDataType
->mTotalSize
;
1025 pNewField
->mOffset
= mNewDataType
->mTotalSize
+ ALIGN_STUFF(mNewDataType
->mTotalSize
, Align
);
1027 if (mNewDataType
->mMembers
== NULL
) {
1028 mNewDataType
->mMembers
= pNewField
;
1029 pNewField
->mNext
= NULL
;
1031 for (pTmp
= mNewDataType
->mMembers
; pTmp
->mNext
!= NULL
; pTmp
= pTmp
->mNext
)
1033 pTmp
->mNext
= pNewField
;
1034 pNewField
->mNext
= NULL
;
1037 mNewDataType
->mAlign
= MIN (mPackAlign
, MAX (pFieldType
->mAlign
, mNewDataType
->mAlign
));
1038 mNewDataType
->mTotalSize
= pNewField
->mOffset
+ (pNewField
->mFieldType
->mTotalSize
) * ((ArrayNum
== 0) ? 1 : ArrayNum
);
1040 return VFR_RETURN_SUCCESS
;
1044 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1048 if (mNewDataType
->mTypeName
[0] == '\0') {
1052 if ((mNewDataType
->mTotalSize
% mNewDataType
->mAlign
) !=0) {
1053 mNewDataType
->mTotalSize
+= ALIGN_STUFF (mNewDataType
->mTotalSize
, mNewDataType
->mAlign
);
1056 RegisterNewType (mNewDataType
);
1057 if (mFirstNewDataTypeName
== NULL
) {
1058 mFirstNewDataTypeName
= mNewDataType
->mTypeName
;
1061 mNewDataType
= NULL
;
1065 CVfrVarDataTypeDB::GetDataType (
1067 OUT SVfrDataType
**DataType
1070 SVfrDataType
*pDataType
= NULL
;
1072 if (TypeName
== NULL
) {
1073 return VFR_RETURN_ERROR_SKIPED
;
1076 if (DataType
== NULL
) {
1077 return VFR_RETURN_FATAL_ERROR
;
1082 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1083 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1084 *DataType
= pDataType
;
1085 return VFR_RETURN_SUCCESS
;
1089 return VFR_RETURN_UNDEFINED
;
1093 CVfrVarDataTypeDB::GetDataTypeSize (
1098 SVfrDataType
*pDataType
= NULL
;
1101 return VFR_RETURN_FATAL_ERROR
;
1105 DataType
= DataType
& 0x0F;
1108 // For user defined data type, the size can't be got by this function.
1110 if (DataType
== EFI_IFR_TYPE_OTHER
) {
1111 return VFR_RETURN_SUCCESS
;
1114 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1115 if (DataType
== pDataType
->mType
) {
1116 *Size
= pDataType
->mTotalSize
;
1117 return VFR_RETURN_SUCCESS
;
1121 return VFR_RETURN_UNDEFINED
;
1125 CVfrVarDataTypeDB::GetDataTypeSize (
1130 SVfrDataType
*pDataType
= NULL
;
1133 return VFR_RETURN_FATAL_ERROR
;
1138 for (pDataType
= mDataTypeList
; pDataType
!= NULL
; pDataType
= pDataType
->mNext
) {
1139 if (strcmp (TypeName
, pDataType
->mTypeName
) == 0) {
1140 *Size
= pDataType
->mTotalSize
;
1141 return VFR_RETURN_SUCCESS
;
1145 return VFR_RETURN_UNDEFINED
;
1149 CVfrVarDataTypeDB::GetDataFieldInfo (
1156 CHAR8 TName
[MAX_NAME_LEN
], FName
[MAX_NAME_LEN
];
1157 UINT32 ArrayIdx
, Tmp
;
1158 SVfrDataType
*pType
= NULL
;
1159 SVfrDataField
*pField
= NULL
;
1162 Type
= EFI_IFR_TYPE_OTHER
;
1165 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr
, TName
), VFR_RETURN_SUCCESS
);
1166 CHECK_ERROR_RETURN (GetDataType (TName
, &pType
), VFR_RETURN_SUCCESS
);
1169 // if it is not struct data type
1171 Type
= pType
->mType
;
1172 Size
= pType
->mTotalSize
;
1174 while (*VarStr
!= '\0') {
1175 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr
, FName
, ArrayIdx
), VFR_RETURN_SUCCESS
);
1176 CHECK_ERROR_RETURN(GetTypeField (FName
, pType
, pField
), VFR_RETURN_SUCCESS
);
1177 pType
= pField
->mFieldType
;
1178 CHECK_ERROR_RETURN(GetFieldOffset (pField
, ArrayIdx
, Tmp
), VFR_RETURN_SUCCESS
);
1179 Offset
= (UINT16
) (Offset
+ Tmp
);
1180 Type
= GetFieldWidth (pField
);
1181 Size
= GetFieldSize (pField
, ArrayIdx
);
1183 return VFR_RETURN_SUCCESS
;
1187 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1188 OUT CHAR8
***NameList
,
1189 OUT UINT32
*ListSize
1193 SVfrDataType
*pType
;
1195 if ((NameList
== NULL
) || (ListSize
== NULL
)) {
1196 return VFR_RETURN_FATAL_ERROR
;
1202 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1203 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1208 if (*ListSize
== 0) {
1209 return VFR_RETURN_SUCCESS
;
1212 if ((*NameList
= new CHAR8
*[*ListSize
]) == NULL
) {
1214 return VFR_RETURN_OUT_FOR_RESOURCES
;
1217 for (Index
= 0, pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
, Index
++) {
1218 if (_IS_INTERNAL_TYPE(pType
->mTypeName
) == FALSE
) {
1219 (*NameList
)[Index
] = pType
->mTypeName
;
1222 return VFR_RETURN_SUCCESS
;
1226 CVfrVarDataTypeDB::IsTypeNameDefined (
1230 SVfrDataType
*pType
;
1232 if (TypeName
== NULL
) {
1236 for (pType
= mDataTypeList
; pType
!= NULL
; pType
= pType
->mNext
) {
1237 if (strcmp (pType
->mTypeName
, TypeName
) == 0) {
1246 CVfrVarDataTypeDB::Dump (
1250 SVfrDataType
*pTNode
;
1251 SVfrDataField
*pFNode
;
1253 fprintf (File
, "\n\n***************************************************************\n");
1254 fprintf (File
, "\t\tmPackAlign = %x\n", mPackAlign
);
1255 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1256 fprintf (File
, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1257 fprintf (File
, "\t\tstruct %s {\n", pTNode
->mTypeName
);
1258 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1259 if (pFNode
->mArrayNum
> 0) {
1260 fprintf (File
, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1261 pFNode
->mFieldName
, pFNode
->mArrayNum
, pFNode
->mFieldType
->mTypeName
);
1263 fprintf (File
, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode
->mOffset
, pFNode
->mOffset
,
1264 pFNode
->mFieldName
, pFNode
->mFieldType
->mTypeName
);
1267 fprintf (File
, "\t\t};\n");
1268 fprintf (File
, "---------------------------------------------------------------\n");
1270 fprintf (File
, "***************************************************************\n");
1273 #ifdef CVFR_VARDATATYPEDB_DEBUG
1275 CVfrVarDataTypeDB::ParserDB (
1279 SVfrDataType
*pTNode
;
1280 SVfrDataField
*pFNode
;
1282 printf ("***************************************************************\n");
1283 printf ("\t\tmPackAlign = %x\n", mPackAlign
);
1284 for (pTNode
= mDataTypeList
; pTNode
!= NULL
; pTNode
= pTNode
->mNext
) {
1285 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode
->mTypeName
, pTNode
->mAlign
, pTNode
->mTotalSize
);
1286 printf ("\t\tstruct %s {\n", pTNode
->mTypeName
);
1287 for (pFNode
= pTNode
->mMembers
; pFNode
!= NULL
; pFNode
= pFNode
->mNext
) {
1288 printf ("\t\t\t%s\t%s\n", pFNode
->mFieldType
->mTypeName
, pFNode
->mFieldName
);
1290 printf ("\t\t};\n");
1291 printf ("---------------------------------------------------------------\n");
1293 printf ("***************************************************************\n");
1297 SVfrVarStorageNode::SVfrVarStorageNode (
1299 IN CHAR8
*StoreName
,
1300 IN EFI_VARSTORE_ID VarStoreId
,
1301 IN EFI_STRING_ID VarName
,
1309 memset (&Guid
, 0, sizeof (EFI_GUID
));
1311 if (StoreName
!= NULL
) {
1312 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1313 strcpy (mVarStoreName
, StoreName
);
1315 mVarStoreName
= NULL
;
1318 mVarStoreId
= VarStoreId
;
1319 mVarStoreType
= EFI_VFR_VARSTORE_EFI
;
1320 mStorageInfo
.mEfiVar
.mEfiVarName
= VarName
;
1321 mStorageInfo
.mEfiVar
.mEfiVarSize
= VarSize
;
1322 mAssignedFlag
= Flag
;
1325 SVfrVarStorageNode::SVfrVarStorageNode (
1327 IN CHAR8
*StoreName
,
1328 IN EFI_VARSTORE_ID VarStoreId
,
1329 IN SVfrDataType
*DataType
,
1336 memset (&Guid
, 0, sizeof (EFI_GUID
));
1338 if (StoreName
!= NULL
) {
1339 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1340 strcpy (mVarStoreName
, StoreName
);
1342 mVarStoreName
= NULL
;
1345 mVarStoreId
= VarStoreId
;
1346 mVarStoreType
= EFI_VFR_VARSTORE_BUFFER
;
1347 mStorageInfo
.mDataType
= DataType
;
1348 mAssignedFlag
= Flag
;
1351 SVfrVarStorageNode::SVfrVarStorageNode (
1352 IN CHAR8
*StoreName
,
1353 IN EFI_VARSTORE_ID VarStoreId
1356 if (StoreName
!= NULL
) {
1357 mVarStoreName
= new CHAR8
[strlen(StoreName
) + 1];
1358 strcpy (mVarStoreName
, StoreName
);
1360 mVarStoreName
= NULL
;
1363 mVarStoreId
= VarStoreId
;
1364 mVarStoreType
= EFI_VFR_VARSTORE_NAME
;
1365 mStorageInfo
.mNameSpace
.mNameTable
= new EFI_VARSTORE_ID
[DEFAULT_NAME_TABLE_ITEMS
];
1366 mStorageInfo
.mNameSpace
.mTableSize
= 0;
1369 SVfrVarStorageNode::~SVfrVarStorageNode (
1373 if (mVarStoreName
!= NULL
) {
1374 delete mVarStoreName
;
1377 if (mVarStoreType
== EFI_VFR_VARSTORE_NAME
) {
1378 delete mStorageInfo
.mNameSpace
.mNameTable
;
1382 CVfrDataStorage::CVfrDataStorage (
1388 for (Index
= 0; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1389 mFreeVarStoreIdBitMap
[Index
] = 0;
1392 // Question ID 0 is reserved.
1393 mFreeVarStoreIdBitMap
[0] = 0x80000000;
1395 mBufferVarStoreList
= NULL
;
1396 mEfiVarStoreList
= NULL
;
1397 mNameVarStoreList
= NULL
;
1398 mCurrVarStorageNode
= NULL
;
1399 mNewVarStorageNode
= NULL
;
1402 CVfrDataStorage::~CVfrDataStorage (
1406 SVfrVarStorageNode
*pNode
;
1408 while (mBufferVarStoreList
!= NULL
) {
1409 pNode
= mBufferVarStoreList
;
1410 mBufferVarStoreList
= mBufferVarStoreList
->mNext
;
1413 while (mEfiVarStoreList
!= NULL
) {
1414 pNode
= mEfiVarStoreList
;
1415 mEfiVarStoreList
= mEfiVarStoreList
->mNext
;
1418 while (mNameVarStoreList
!= NULL
) {
1419 pNode
= mNameVarStoreList
;
1420 mNameVarStoreList
= mNameVarStoreList
->mNext
;
1423 if (mNewVarStorageNode
!= NULL
) {
1424 delete mNewVarStorageNode
;
1429 CVfrDataStorage::GetFreeVarStoreId (
1430 EFI_VFR_VARSTORE_TYPE VarType
1433 UINT32 Index
, Mask
, Offset
;
1436 // Assign the different ID range for the different type VarStore to support Framework Vfr
1439 if ((!VfrCompatibleMode
) || (VarType
== EFI_VFR_VARSTORE_BUFFER
)) {
1441 } else if (VarType
== EFI_VFR_VARSTORE_EFI
) {
1443 } else if (VarType
== EFI_VFR_VARSTORE_NAME
) {
1447 for (; Index
< EFI_FREE_VARSTORE_ID_BITMAP_SIZE
; Index
++) {
1448 if (mFreeVarStoreIdBitMap
[Index
] != 0xFFFFFFFF) {
1453 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
1454 if ((mFreeVarStoreIdBitMap
[Index
] & Mask
) == 0) {
1455 mFreeVarStoreIdBitMap
[Index
] |= Mask
;
1456 return (EFI_VARSTORE_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
1460 return EFI_VARSTORE_ID_INVALID
;
1464 CVfrDataStorage::ChekVarStoreIdFree (
1465 IN EFI_VARSTORE_ID VarStoreId
1468 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1469 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1471 return (mFreeVarStoreIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
1475 CVfrDataStorage::MarkVarStoreIdUsed (
1476 IN EFI_VARSTORE_ID VarStoreId
1479 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1480 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1482 mFreeVarStoreIdBitMap
[Index
] |= (0x80000000 >> Offset
);
1486 CVfrDataStorage::MarkVarStoreIdUnused (
1487 IN EFI_VARSTORE_ID VarStoreId
1490 UINT32 Index
= (VarStoreId
/ EFI_BITS_PER_UINT32
);
1491 UINT32 Offset
= (VarStoreId
% EFI_BITS_PER_UINT32
);
1493 mFreeVarStoreIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
1497 CVfrDataStorage::DeclareNameVarStoreBegin (
1501 SVfrVarStorageNode
*pNode
= NULL
;
1502 EFI_VARSTORE_ID VarStoreId
;
1504 if (StoreName
== NULL
) {
1505 return VFR_RETURN_FATAL_ERROR
;
1508 if (GetVarStoreId (StoreName
, &VarStoreId
) == VFR_RETURN_SUCCESS
) {
1509 return VFR_RETURN_REDEFINED
;
1512 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME
);
1513 if ((pNode
= new SVfrVarStorageNode (StoreName
, VarStoreId
)) == NULL
) {
1514 return VFR_RETURN_UNDEFINED
;
1517 mNewVarStorageNode
= pNode
;
1519 return VFR_RETURN_SUCCESS
;
1523 CVfrDataStorage::NameTableAddItem (
1524 IN EFI_STRING_ID Item
1527 EFI_VARSTORE_ID
*NewTable
, *OldTable
;
1530 OldTable
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
;
1531 TableSize
= mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
;
1533 if ((TableSize
!= 0) && ((TableSize
% DEFAULT_NAME_TABLE_ITEMS
) == 0)) {
1534 if ((NewTable
= new EFI_VARSTORE_ID
[TableSize
+ DEFAULT_NAME_TABLE_ITEMS
]) == NULL
) {
1535 return VFR_RETURN_OUT_FOR_RESOURCES
;
1537 memcpy (NewTable
, OldTable
, TableSize
);
1538 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
= NewTable
;
1541 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[TableSize
++] = Item
;
1542 mNewVarStorageNode
->mStorageInfo
.mNameSpace
.mTableSize
= TableSize
;
1544 return VFR_RETURN_SUCCESS
;
1548 CVfrDataStorage::DeclareNameVarStoreEnd (
1552 mNewVarStorageNode
->mGuid
= *Guid
;
1553 mNewVarStorageNode
->mNext
= mNameVarStoreList
;
1554 mNameVarStoreList
= mNewVarStorageNode
;
1556 mNewVarStorageNode
= NULL
;
1558 return VFR_RETURN_SUCCESS
;
1562 CVfrDataStorage::DeclareEfiVarStore (
1563 IN CHAR8
*StoreName
,
1565 IN EFI_STRING_ID NameStrId
,
1570 SVfrVarStorageNode
*pNode
;
1571 EFI_VARSTORE_ID VarStoreId
;
1573 if ((StoreName
== NULL
) || (Guid
== NULL
)) {
1574 return VFR_RETURN_FATAL_ERROR
;
1577 if (VarSize
> sizeof (UINT64
)) {
1578 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR
;
1581 if (GetVarStoreId (StoreName
, &VarStoreId
) == VFR_RETURN_SUCCESS
) {
1582 return VFR_RETURN_REDEFINED
;
1585 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI
);
1586 if ((pNode
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, NameStrId
, VarSize
, Flag
)) == NULL
) {
1587 return VFR_RETURN_OUT_FOR_RESOURCES
;
1590 pNode
->mNext
= mEfiVarStoreList
;
1591 mEfiVarStoreList
= pNode
;
1593 return VFR_RETURN_SUCCESS
;
1597 CVfrDataStorage::DeclareBufferVarStore (
1598 IN CHAR8
*StoreName
,
1600 IN CVfrVarDataTypeDB
*DataTypeDB
,
1602 IN EFI_VARSTORE_ID VarStoreId
,
1606 SVfrVarStorageNode
*pNew
= NULL
;
1607 SVfrDataType
*pDataType
= NULL
;
1608 EFI_VARSTORE_ID TempVarStoreId
;
1610 if ((StoreName
== NULL
) || (Guid
== NULL
) || (DataTypeDB
== NULL
)) {
1611 return VFR_RETURN_FATAL_ERROR
;
1614 if (GetVarStoreId (StoreName
, &TempVarStoreId
) == VFR_RETURN_SUCCESS
) {
1615 return VFR_RETURN_REDEFINED
;
1618 CHECK_ERROR_RETURN(DataTypeDB
->GetDataType (TypeName
, &pDataType
), VFR_RETURN_SUCCESS
);
1620 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1621 VarStoreId
= GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER
);
1623 if (ChekVarStoreIdFree (VarStoreId
) == FALSE
) {
1624 return VFR_RETURN_VARSTOREID_REDEFINED
;
1626 MarkVarStoreIdUsed (VarStoreId
);
1629 if ((pNew
= new SVfrVarStorageNode (Guid
, StoreName
, VarStoreId
, pDataType
, Flag
)) == NULL
) {
1630 return VFR_RETURN_OUT_FOR_RESOURCES
;
1633 pNew
->mNext
= mBufferVarStoreList
;
1634 mBufferVarStoreList
= pNew
;
1636 if (gCVfrBufferConfig
.Register(StoreName
) != 0) {
1637 return VFR_RETURN_FATAL_ERROR
;
1640 return VFR_RETURN_SUCCESS
;
1644 CVfrDataStorage::GetVarStoreByDataType (
1645 IN CHAR8
*DataTypeName
,
1646 OUT SVfrVarStorageNode
**VarNode
1649 SVfrVarStorageNode
*pNode
;
1650 SVfrVarStorageNode
*MatchNode
;
1653 // Framework VFR uses Data type name as varstore name, so don't need check again.
1655 if (VfrCompatibleMode
) {
1656 return VFR_RETURN_UNDEFINED
;
1660 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1661 if (strcmp (pNode
->mStorageInfo
.mDataType
->mTypeName
, DataTypeName
) == 0) {
1662 if (MatchNode
== NULL
) {
1666 // More than one varstores referred the same data structures.
1668 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR
;
1673 if (MatchNode
== NULL
) {
1674 return VFR_RETURN_UNDEFINED
;
1677 *VarNode
= MatchNode
;
1678 return VFR_RETURN_SUCCESS
;
1682 CVfrDataStorage::GetVarStoreId (
1683 IN CHAR8
*StoreName
,
1684 OUT EFI_VARSTORE_ID
*VarStoreId
1687 EFI_VFR_RETURN_CODE ReturnCode
;
1688 SVfrVarStorageNode
*pNode
;
1690 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1691 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1692 mCurrVarStorageNode
= pNode
;
1693 *VarStoreId
= pNode
->mVarStoreId
;
1694 return VFR_RETURN_SUCCESS
;
1698 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1699 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1700 mCurrVarStorageNode
= pNode
;
1701 *VarStoreId
= pNode
->mVarStoreId
;
1702 return VFR_RETURN_SUCCESS
;
1706 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1707 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1708 mCurrVarStorageNode
= pNode
;
1709 *VarStoreId
= pNode
->mVarStoreId
;
1710 return VFR_RETURN_SUCCESS
;
1714 mCurrVarStorageNode
= NULL
;
1715 *VarStoreId
= EFI_VARSTORE_ID_INVALID
;
1718 // Assume that Data strucutre name is used as StoreName, and check again.
1720 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
);
1721 if (pNode
!= NULL
) {
1722 mCurrVarStorageNode
= pNode
;
1723 *VarStoreId
= pNode
->mVarStoreId
;
1730 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1731 IN CHAR8
*StoreName
,
1732 OUT CHAR8
**DataTypeName
1735 SVfrVarStorageNode
*pNode
;
1736 EFI_VFR_RETURN_CODE ReturnCode
;
1738 if ((StoreName
== NULL
) || (DataTypeName
== NULL
)) {
1739 return VFR_RETURN_FATAL_ERROR
;
1742 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1743 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1748 ReturnCode
= VFR_RETURN_UNDEFINED
;
1750 // Assume that Data strucutre name is used as StoreName, and check again.
1752 if (pNode
== NULL
) {
1753 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
);
1756 if (pNode
== NULL
) {
1760 if (pNode
->mStorageInfo
.mDataType
== NULL
) {
1761 return VFR_RETURN_FATAL_ERROR
;
1764 *DataTypeName
= pNode
->mStorageInfo
.mDataType
->mTypeName
;
1765 return VFR_RETURN_SUCCESS
;
1769 CVfrDataStorage::GetVarStoreType (
1770 IN CHAR8
*StoreName
,
1771 OUT EFI_VFR_VARSTORE_TYPE
&VarStoreType
1774 SVfrVarStorageNode
*pNode
;
1775 EFI_VFR_RETURN_CODE ReturnCode
;
1777 if (StoreName
== NULL
) {
1778 return VFR_RETURN_FATAL_ERROR
;
1781 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1782 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1783 VarStoreType
= pNode
->mVarStoreType
;
1784 return VFR_RETURN_SUCCESS
;
1788 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1789 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1790 VarStoreType
= pNode
->mVarStoreType
;
1791 return VFR_RETURN_SUCCESS
;
1795 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1796 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1797 VarStoreType
= pNode
->mVarStoreType
;
1798 return VFR_RETURN_SUCCESS
;
1802 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1805 // Assume that Data strucutre name is used as StoreName, and check again.
1807 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
);
1808 if (pNode
!= NULL
) {
1809 VarStoreType
= pNode
->mVarStoreType
;
1815 EFI_VFR_VARSTORE_TYPE
1816 CVfrDataStorage::GetVarStoreType (
1817 IN EFI_VARSTORE_ID VarStoreId
1820 SVfrVarStorageNode
*pNode
;
1821 EFI_VFR_VARSTORE_TYPE VarStoreType
;
1823 VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1825 if (VarStoreId
== EFI_VARSTORE_ID_INVALID
) {
1826 return VarStoreType
;
1829 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1830 if (pNode
->mVarStoreId
== VarStoreId
) {
1831 VarStoreType
= pNode
->mVarStoreType
;
1832 return VarStoreType
;
1836 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1837 if (pNode
->mVarStoreId
== VarStoreId
) {
1838 VarStoreType
= pNode
->mVarStoreType
;
1839 return VarStoreType
;
1843 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1844 if (pNode
->mVarStoreId
== VarStoreId
) {
1845 VarStoreType
= pNode
->mVarStoreType
;
1846 return VarStoreType
;
1850 return VarStoreType
;
1854 CVfrDataStorage::GetVarStoreName (
1855 IN EFI_VARSTORE_ID VarStoreId
,
1856 OUT CHAR8
**VarStoreName
1859 SVfrVarStorageNode
*pNode
;
1861 if (VarStoreName
== NULL
) {
1862 return VFR_RETURN_FATAL_ERROR
;
1865 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1866 if (pNode
->mVarStoreId
== VarStoreId
) {
1867 *VarStoreName
= pNode
->mVarStoreName
;
1868 return VFR_RETURN_SUCCESS
;
1872 for (pNode
= mEfiVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1873 if (pNode
->mVarStoreId
== VarStoreId
) {
1874 *VarStoreName
= pNode
->mVarStoreName
;
1875 return VFR_RETURN_SUCCESS
;
1879 for (pNode
= mNameVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1880 if (pNode
->mVarStoreId
== VarStoreId
) {
1881 *VarStoreName
= pNode
->mVarStoreName
;
1882 return VFR_RETURN_SUCCESS
;
1886 *VarStoreName
= NULL
;
1887 return VFR_RETURN_UNDEFINED
;
1891 CVfrDataStorage::GetEfiVarStoreInfo (
1892 IN OUT EFI_VARSTORE_INFO
*Info
1896 return VFR_RETURN_FATAL_ERROR
;
1899 if (mCurrVarStorageNode
== NULL
) {
1900 return VFR_RETURN_GET_EFIVARSTORE_ERROR
;
1903 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarName
;
1904 Info
->mVarTotalSize
= mCurrVarStorageNode
->mStorageInfo
.mEfiVar
.mEfiVarSize
;
1905 switch (Info
->mVarTotalSize
) {
1907 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
1910 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_16
;
1913 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_32
;
1916 Info
->mVarType
= EFI_IFR_TYPE_NUM_SIZE_64
;
1919 return VFR_RETURN_FATAL_ERROR
;
1922 return VFR_RETURN_SUCCESS
;
1926 CVfrDataStorage::GetNameVarStoreInfo (
1927 OUT EFI_VARSTORE_INFO
*Info
,
1932 return VFR_RETURN_FATAL_ERROR
;
1935 if (mCurrVarStorageNode
== NULL
) {
1936 return VFR_RETURN_GET_NVVARSTORE_ERROR
;
1940 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
1942 if (VfrCompatibleMode
) {
1944 return VFR_RETURN_ERROR_ARRARY_NUM
;
1949 Info
->mInfo
.mVarName
= mCurrVarStorageNode
->mStorageInfo
.mNameSpace
.mNameTable
[Index
];
1951 return VFR_RETURN_SUCCESS
;
1955 CVfrDataStorage::BufferVarStoreRequestElementAdd (
1956 IN CHAR8
*StoreName
,
1957 IN EFI_VARSTORE_INFO
&Info
1960 SVfrVarStorageNode
*pNode
= NULL
;
1961 EFI_IFR_TYPE_VALUE Value
= gZeroEfiIfrTypeValue
;
1962 EFI_VFR_RETURN_CODE ReturnCode
;
1964 for (pNode
= mBufferVarStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1965 if (strcmp (pNode
->mVarStoreName
, StoreName
) == 0) {
1970 ReturnCode
= VFR_RETURN_UNDEFINED
;
1972 // Assume that Data strucutre name is used as StoreName, and check again.
1974 if (pNode
== NULL
) {
1975 ReturnCode
= GetVarStoreByDataType (StoreName
, &pNode
);
1978 if (pNode
== NULL
) {
1982 gCVfrBufferConfig
.Open ();
1984 if (gCVfrBufferConfig
.Write ('a', StoreName
, NULL
, EFI_IFR_TYPE_NUM_SIZE_8
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
) != 0) {
1985 return VFR_RETURN_FATAL_ERROR
;
1987 gCVfrBufferConfig
.Close ();
1989 return VFR_RETURN_SUCCESS
;
1992 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
1993 IN EFI_IFR_DEFAULTSTORE
*ObjBinAddr
,
1995 IN EFI_STRING_ID DefaultStoreNameId
,
1999 mObjBinAddr
= ObjBinAddr
;
2001 if (RefName
!= NULL
) {
2002 mRefName
= new CHAR8
[strlen (RefName
) + 1];
2003 strcpy (mRefName
, RefName
);
2009 mDefaultId
= DefaultId
;
2010 mDefaultStoreNameId
= DefaultStoreNameId
;
2013 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2017 if (mRefName
!= NULL
) {
2022 CVfrDefaultStore::CVfrDefaultStore (
2026 mDefaultStoreList
= NULL
;
2029 CVfrDefaultStore::~CVfrDefaultStore (
2033 SVfrDefaultStoreNode
*pTmp
= NULL
;
2035 while (mDefaultStoreList
!= NULL
) {
2036 pTmp
= mDefaultStoreList
;
2037 mDefaultStoreList
= mDefaultStoreList
->mNext
;
2043 CVfrDefaultStore::RegisterDefaultStore (
2044 IN CHAR8
*ObjBinAddr
,
2046 IN EFI_STRING_ID DefaultStoreNameId
,
2050 SVfrDefaultStoreNode
*pNode
= NULL
;
2052 if (RefName
== NULL
) {
2053 return VFR_RETURN_FATAL_ERROR
;
2056 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2057 if (strcmp (pNode
->mRefName
, RefName
) == 0) {
2058 return VFR_RETURN_REDEFINED
;
2062 if ((pNode
= new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE
*)ObjBinAddr
, RefName
, DefaultStoreNameId
, DefaultId
)) == NULL
) {
2063 return VFR_RETURN_OUT_FOR_RESOURCES
;
2066 pNode
->mNext
= mDefaultStoreList
;
2067 mDefaultStoreList
= pNode
;
2069 return VFR_RETURN_SUCCESS
;
2073 * assign new reference name or new default store name id only if
2074 * the original is invalid
2077 CVfrDefaultStore::ReRegisterDefaultStoreById (
2078 IN UINT16 DefaultId
,
2080 IN EFI_STRING_ID DefaultStoreNameId
2083 SVfrDefaultStoreNode
*pNode
= NULL
;
2085 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2086 if (pNode
->mDefaultId
== DefaultId
) {
2091 if (pNode
== NULL
) {
2092 return VFR_RETURN_UNDEFINED
;
2094 if (pNode
->mDefaultStoreNameId
== EFI_STRING_ID_INVALID
) {
2095 pNode
->mDefaultStoreNameId
= DefaultStoreNameId
;
2096 if (pNode
->mObjBinAddr
!= NULL
) {
2097 pNode
->mObjBinAddr
->DefaultName
= DefaultStoreNameId
;
2100 return VFR_RETURN_REDEFINED
;
2103 if (RefName
!= NULL
) {
2104 delete pNode
->mRefName
;
2105 pNode
->mRefName
= new CHAR8
[strlen (RefName
) + 1];
2106 if (pNode
->mRefName
!= NULL
) {
2107 strcpy (pNode
->mRefName
, RefName
);
2112 return VFR_RETURN_SUCCESS
;
2116 CVfrDefaultStore::DefaultIdRegistered (
2120 SVfrDefaultStoreNode
*pNode
= NULL
;
2122 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2123 if (pNode
->mDefaultId
== DefaultId
) {
2132 CVfrDefaultStore::GetDefaultId (
2134 OUT UINT16
*DefaultId
2137 SVfrDefaultStoreNode
*pTmp
= NULL
;
2139 if (DefaultId
== NULL
) {
2140 return VFR_RETURN_FATAL_ERROR
;
2143 for (pTmp
= mDefaultStoreList
; pTmp
!= NULL
; pTmp
= pTmp
->mNext
) {
2144 if (strcmp (pTmp
->mRefName
, RefName
) == 0) {
2145 *DefaultId
= pTmp
->mDefaultId
;
2146 return VFR_RETURN_SUCCESS
;
2150 return VFR_RETURN_UNDEFINED
;
2154 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2155 IN EFI_VARSTORE_ID DefaultId
,
2156 IN EFI_VARSTORE_INFO
&Info
,
2157 IN CHAR8
*VarStoreName
,
2159 IN EFI_IFR_TYPE_VALUE Value
2162 SVfrDefaultStoreNode
*pNode
= NULL
;
2163 CHAR8 NewAltCfg
[2 * 2 * sizeof (UINT16
) + 1] = {0,};
2164 INTN Returnvalue
= 0;
2166 if (VarStoreName
== NULL
) {
2167 return VFR_RETURN_FATAL_ERROR
;
2170 for (pNode
= mDefaultStoreList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2171 if (pNode
->mDefaultId
== DefaultId
) {
2176 if (pNode
== NULL
) {
2177 return VFR_RETURN_UNDEFINED
;
2180 gCVfrBufferConfig
.Open ();
2182 sprintf (NewAltCfg
, "%04x", pNode
->mDefaultId
);
2183 if ((Returnvalue
= gCVfrBufferConfig
.Select(VarStoreName
)) == 0) {
2184 if ((Returnvalue
= gCVfrBufferConfig
.Write ('a', VarStoreName
, NewAltCfg
, Type
, Info
.mInfo
.mVarOffset
, Info
.mVarTotalSize
, Value
)) != 0) {
2189 gCVfrBufferConfig
.Close ();
2191 return VFR_RETURN_SUCCESS
;
2194 gCVfrBufferConfig
.Close ();
2195 return (EFI_VFR_RETURN_CODE
)Returnvalue
;
2198 SVfrRuleNode::SVfrRuleNode (
2203 if (RuleName
!= NULL
) {
2204 mRuleName
= new CHAR8
[strlen (RuleName
) + 1];
2205 strcpy (mRuleName
, RuleName
);
2214 SVfrRuleNode::~SVfrRuleNode (
2218 if (mRuleName
!= NULL
) {
2223 CVfrRulesDB::CVfrRulesDB ()
2226 mFreeRuleId
= EFI_VARSTORE_ID_START
;
2229 CVfrRulesDB::~CVfrRulesDB ()
2231 SVfrRuleNode
*pNode
;
2233 while(mRuleList
!= NULL
) {
2235 mRuleList
= mRuleList
->mNext
;
2241 CVfrRulesDB::RegisterRule (
2247 if (RuleName
== NULL
) {
2251 if ((pNew
= new SVfrRuleNode (RuleName
, mFreeRuleId
)) == NULL
) {
2257 pNew
->mNext
= mRuleList
;
2262 CVfrRulesDB::GetRuleId (
2266 SVfrRuleNode
*pNode
;
2268 if (RuleName
== NULL
) {
2269 return EFI_RULE_ID_INVALID
;
2272 for (pNode
= mRuleList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2273 if (strcmp (pNode
->mRuleName
, RuleName
) == 0) {
2274 return pNode
->mRuleId
;
2278 return EFI_RULE_ID_INVALID
;
2281 CVfrRulesDB gCVfrRulesDB
;
2283 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2287 mVarStoreId
= EFI_VARSTORE_ID_INVALID
;
2288 mInfo
.mVarName
= EFI_STRING_ID_INVALID
;
2289 mInfo
.mVarOffset
= EFI_VAROFFSET_INVALID
;
2290 mVarType
= EFI_IFR_TYPE_OTHER
;
2294 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2295 IN EFI_VARSTORE_INFO
&Info
2298 mVarStoreId
= Info
.mVarStoreId
;
2299 mInfo
.mVarName
= Info
.mInfo
.mVarName
;
2300 mInfo
.mVarOffset
= Info
.mInfo
.mVarOffset
;
2301 mVarType
= Info
.mVarType
;
2302 mVarTotalSize
= Info
.mVarTotalSize
;
2306 EFI_VARSTORE_INFO::operator == (
2307 IN EFI_VARSTORE_INFO
*Info
2310 if ((mVarStoreId
== Info
->mVarStoreId
) &&
2311 (mInfo
.mVarName
== Info
->mInfo
.mVarName
) &&
2312 (mInfo
.mVarOffset
== Info
->mInfo
.mVarOffset
) &&
2313 (mVarType
== Info
->mVarType
) &&
2314 (mVarTotalSize
== Info
->mVarTotalSize
)) {
2321 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo
;
2324 CVfrQuestionDB::GetFreeQuestionId (
2328 UINT32 Index
, Mask
, Offset
;
2330 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2331 if (mFreeQIdBitMap
[Index
] != 0xFFFFFFFF) {
2336 for (Offset
= 0, Mask
= 0x80000000; Mask
!= 0; Mask
>>= 1, Offset
++) {
2337 if ((mFreeQIdBitMap
[Index
] & Mask
) == 0) {
2338 mFreeQIdBitMap
[Index
] |= Mask
;
2339 return (EFI_QUESTION_ID
)((Index
<< EFI_BITS_SHIFT_PER_UINT32
) + Offset
);
2343 return EFI_QUESTION_ID_INVALID
;
2347 CVfrQuestionDB::ChekQuestionIdFree (
2348 IN EFI_QUESTION_ID QId
2351 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2352 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2354 return (mFreeQIdBitMap
[Index
] & (0x80000000 >> Offset
)) == 0;
2358 CVfrQuestionDB::MarkQuestionIdUsed (
2359 IN EFI_QUESTION_ID QId
2362 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2363 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2365 mFreeQIdBitMap
[Index
] |= (0x80000000 >> Offset
);
2369 CVfrQuestionDB::MarkQuestionIdUnused (
2370 IN EFI_QUESTION_ID QId
2373 UINT32 Index
= (QId
/ EFI_BITS_PER_UINT32
);
2374 UINT32 Offset
= (QId
% EFI_BITS_PER_UINT32
);
2376 mFreeQIdBitMap
[Index
] &= ~(0x80000000 >> Offset
);
2379 SVfrQuestionNode::SVfrQuestionNode (
2387 mQuestionId
= EFI_QUESTION_ID_INVALID
;
2390 mQtype
= QUESTION_NORMAL
;
2393 mName
= new CHAR8
[strlen ("$DEFAULT") + 1];
2394 strcpy (mName
, "$DEFAULT");
2396 mName
= new CHAR8
[strlen (Name
) + 1];
2397 strcpy (mName
, Name
);
2400 if (VarIdStr
!= NULL
) {
2401 mVarIdStr
= new CHAR8
[strlen (VarIdStr
) + 1];
2402 strcpy (mVarIdStr
, VarIdStr
);
2404 mVarIdStr
= new CHAR8
[strlen ("$") + 1];
2405 strcpy (mVarIdStr
, "$");
2409 SVfrQuestionNode::~SVfrQuestionNode (
2413 if (mName
!= NULL
) {
2417 if (mVarIdStr
!= NULL
) {
2422 CVfrQuestionDB::CVfrQuestionDB ()
2426 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2427 mFreeQIdBitMap
[Index
] = 0;
2430 // Question ID 0 is reserved.
2431 mFreeQIdBitMap
[0] = 0x80000000;
2432 mQuestionList
= NULL
;
2435 CVfrQuestionDB::~CVfrQuestionDB ()
2437 SVfrQuestionNode
*pNode
;
2439 while (mQuestionList
!= NULL
) {
2440 pNode
= mQuestionList
;
2441 mQuestionList
= mQuestionList
->mNext
;
2447 // Reset to init state
2450 CVfrQuestionDB::ResetInit(
2455 SVfrQuestionNode
*pNode
;
2457 while (mQuestionList
!= NULL
) {
2458 pNode
= mQuestionList
;
2459 mQuestionList
= mQuestionList
->mNext
;
2463 for (Index
= 0; Index
< EFI_FREE_QUESTION_ID_BITMAP_SIZE
; Index
++) {
2464 mFreeQIdBitMap
[Index
] = 0;
2467 // Question ID 0 is reserved.
2468 mFreeQIdBitMap
[0] = 0x80000000;
2469 mQuestionList
= NULL
;
2473 CVfrQuestionDB::PrintAllQuestion (
2477 SVfrQuestionNode
*pNode
= NULL
;
2479 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2480 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode
->mVarIdStr
, pNode
->mQuestionId
);
2485 CVfrQuestionDB::RegisterQuestion (
2488 IN OUT EFI_QUESTION_ID
&QuestionId
2491 SVfrQuestionNode
*pNode
= NULL
;
2493 if ((Name
!= NULL
) && (FindQuestion(Name
) == VFR_RETURN_SUCCESS
)) {
2494 return VFR_RETURN_REDEFINED
;
2497 if ((pNode
= new SVfrQuestionNode (Name
, VarIdStr
)) == NULL
) {
2498 return VFR_RETURN_OUT_FOR_RESOURCES
;
2501 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2502 QuestionId
= GetFreeQuestionId ();
2505 // For Framework Vfr, don't check question ID conflict.
2507 if (!VfrCompatibleMode
&& ChekQuestionIdFree (QuestionId
) == FALSE
) {
2509 return VFR_RETURN_QUESTIONID_REDEFINED
;
2511 MarkQuestionIdUsed (QuestionId
);
2513 pNode
->mQuestionId
= QuestionId
;
2515 pNode
->mNext
= mQuestionList
;
2516 mQuestionList
= pNode
;
2518 gCFormPkg
.DoPendingAssign (VarIdStr
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2520 return VFR_RETURN_SUCCESS
;
2524 CVfrQuestionDB::RegisterOldDateQuestion (
2525 IN CHAR8
*YearVarId
,
2526 IN CHAR8
*MonthVarId
,
2528 IN OUT EFI_QUESTION_ID
&QuestionId
2531 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2534 if ((YearVarId
== NULL
) || (MonthVarId
== NULL
) || (DayVarId
== NULL
)) {
2538 if ((pNode
[0] = new SVfrQuestionNode (NULL
, YearVarId
, DATE_YEAR_BITMASK
)) == NULL
) {
2541 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MonthVarId
, DATE_MONTH_BITMASK
)) == NULL
) {
2544 if ((pNode
[2] = new SVfrQuestionNode (NULL
, DayVarId
, DATE_DAY_BITMASK
)) == NULL
) {
2548 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2549 QuestionId
= GetFreeQuestionId ();
2551 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2554 MarkQuestionIdUsed (QuestionId
);
2557 pNode
[0]->mQuestionId
= QuestionId
;
2558 pNode
[1]->mQuestionId
= QuestionId
;
2559 pNode
[2]->mQuestionId
= QuestionId
;
2560 pNode
[0]->mQtype
= QUESTION_DATE
;
2561 pNode
[1]->mQtype
= QUESTION_DATE
;
2562 pNode
[2]->mQtype
= QUESTION_DATE
;
2563 pNode
[0]->mNext
= pNode
[1];
2564 pNode
[1]->mNext
= pNode
[2];
2565 pNode
[2]->mNext
= mQuestionList
;
2566 mQuestionList
= pNode
[0];
2568 gCFormPkg
.DoPendingAssign (YearVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2569 gCFormPkg
.DoPendingAssign (MonthVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2570 gCFormPkg
.DoPendingAssign (DayVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2575 for (Index
= 0; Index
< 3; Index
++) {
2576 if (pNode
[Index
] != NULL
) {
2577 delete pNode
[Index
];
2580 QuestionId
= EFI_QUESTION_ID_INVALID
;
2584 CVfrQuestionDB::RegisterNewDateQuestion (
2586 IN CHAR8
*BaseVarId
,
2587 IN OUT EFI_QUESTION_ID
&QuestionId
2590 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2592 CHAR8
*VarIdStr
[3] = {NULL
, };
2595 if (BaseVarId
== NULL
) {
2599 Len
= strlen (BaseVarId
);
2601 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Year") + 1];
2602 if (VarIdStr
[0] != NULL
) {
2603 strcpy (VarIdStr
[0], BaseVarId
);
2604 strcat (VarIdStr
[0], ".Year");
2606 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Month") + 1];
2607 if (VarIdStr
[1] != NULL
) {
2608 strcpy (VarIdStr
[1], BaseVarId
);
2609 strcat (VarIdStr
[1], ".Month");
2611 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Day") + 1];
2612 if (VarIdStr
[2] != NULL
) {
2613 strcpy (VarIdStr
[2], BaseVarId
);
2614 strcat (VarIdStr
[2], ".Day");
2617 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], DATE_YEAR_BITMASK
)) == NULL
) {
2620 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], DATE_MONTH_BITMASK
)) == NULL
) {
2623 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], DATE_DAY_BITMASK
)) == NULL
) {
2627 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2628 QuestionId
= GetFreeQuestionId ();
2630 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2633 MarkQuestionIdUsed (QuestionId
);
2636 pNode
[0]->mQuestionId
= QuestionId
;
2637 pNode
[1]->mQuestionId
= QuestionId
;
2638 pNode
[2]->mQuestionId
= QuestionId
;
2639 pNode
[0]->mQtype
= QUESTION_DATE
;
2640 pNode
[1]->mQtype
= QUESTION_DATE
;
2641 pNode
[2]->mQtype
= QUESTION_DATE
;
2642 pNode
[0]->mNext
= pNode
[1];
2643 pNode
[1]->mNext
= pNode
[2];
2644 pNode
[2]->mNext
= mQuestionList
;
2645 mQuestionList
= pNode
[0];
2647 for (Index
= 0; Index
< 3; Index
++) {
2648 if (VarIdStr
[Index
] != NULL
) {
2649 delete VarIdStr
[Index
];
2653 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2654 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2655 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2660 for (Index
= 0; Index
< 3; Index
++) {
2661 if (pNode
[Index
] != NULL
) {
2662 delete pNode
[Index
];
2665 if (VarIdStr
[Index
] != NULL
) {
2666 delete VarIdStr
[Index
];
2672 CVfrQuestionDB::RegisterOldTimeQuestion (
2673 IN CHAR8
*HourVarId
,
2674 IN CHAR8
*MinuteVarId
,
2675 IN CHAR8
*SecondVarId
,
2676 IN OUT EFI_QUESTION_ID
&QuestionId
2679 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2682 if ((HourVarId
== NULL
) || (MinuteVarId
== NULL
) || (SecondVarId
== NULL
)) {
2686 if ((pNode
[0] = new SVfrQuestionNode (NULL
, HourVarId
, TIME_HOUR_BITMASK
)) == NULL
) {
2689 if ((pNode
[1] = new SVfrQuestionNode (NULL
, MinuteVarId
, TIME_MINUTE_BITMASK
)) == NULL
) {
2692 if ((pNode
[2] = new SVfrQuestionNode (NULL
, SecondVarId
, TIME_SECOND_BITMASK
)) == NULL
) {
2696 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2697 QuestionId
= GetFreeQuestionId ();
2699 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2702 MarkQuestionIdUsed (QuestionId
);
2705 pNode
[0]->mQuestionId
= QuestionId
;
2706 pNode
[1]->mQuestionId
= QuestionId
;
2707 pNode
[2]->mQuestionId
= QuestionId
;
2708 pNode
[0]->mQtype
= QUESTION_TIME
;
2709 pNode
[1]->mQtype
= QUESTION_TIME
;
2710 pNode
[2]->mQtype
= QUESTION_TIME
;
2711 pNode
[0]->mNext
= pNode
[1];
2712 pNode
[1]->mNext
= pNode
[2];
2713 pNode
[2]->mNext
= mQuestionList
;
2714 mQuestionList
= pNode
[0];
2716 gCFormPkg
.DoPendingAssign (HourVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2717 gCFormPkg
.DoPendingAssign (MinuteVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2718 gCFormPkg
.DoPendingAssign (SecondVarId
, (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2723 for (Index
= 0; Index
< 3; Index
++) {
2724 if (pNode
[Index
] != NULL
) {
2725 delete pNode
[Index
];
2728 QuestionId
= EFI_QUESTION_ID_INVALID
;
2732 CVfrQuestionDB::RegisterNewTimeQuestion (
2734 IN CHAR8
*BaseVarId
,
2735 IN OUT EFI_QUESTION_ID
&QuestionId
2738 SVfrQuestionNode
*pNode
[3] = {NULL
, };
2740 CHAR8
*VarIdStr
[3] = {NULL
, };
2743 if (BaseVarId
== NULL
) {
2747 Len
= strlen (BaseVarId
);
2749 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".Hour") + 1];
2750 if (VarIdStr
[0] != NULL
) {
2751 strcpy (VarIdStr
[0], BaseVarId
);
2752 strcat (VarIdStr
[0], ".Hour");
2754 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".Minute") + 1];
2755 if (VarIdStr
[1] != NULL
) {
2756 strcpy (VarIdStr
[1], BaseVarId
);
2757 strcat (VarIdStr
[1], ".Minute");
2759 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".Second") + 1];
2760 if (VarIdStr
[2] != NULL
) {
2761 strcpy (VarIdStr
[2], BaseVarId
);
2762 strcat (VarIdStr
[2], ".Second");
2765 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0], TIME_HOUR_BITMASK
)) == NULL
) {
2768 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1], TIME_MINUTE_BITMASK
)) == NULL
) {
2771 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2], TIME_SECOND_BITMASK
)) == NULL
) {
2775 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2776 QuestionId
= GetFreeQuestionId ();
2778 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2781 MarkQuestionIdUsed (QuestionId
);
2784 pNode
[0]->mQuestionId
= QuestionId
;
2785 pNode
[1]->mQuestionId
= QuestionId
;
2786 pNode
[2]->mQuestionId
= QuestionId
;
2787 pNode
[0]->mQtype
= QUESTION_TIME
;
2788 pNode
[1]->mQtype
= QUESTION_TIME
;
2789 pNode
[2]->mQtype
= QUESTION_TIME
;
2790 pNode
[0]->mNext
= pNode
[1];
2791 pNode
[1]->mNext
= pNode
[2];
2792 pNode
[2]->mNext
= mQuestionList
;
2793 mQuestionList
= pNode
[0];
2795 for (Index
= 0; Index
< 3; Index
++) {
2796 if (VarIdStr
[Index
] != NULL
) {
2797 delete VarIdStr
[Index
];
2801 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2802 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2803 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2808 for (Index
= 0; Index
< 3; Index
++) {
2809 if (pNode
[Index
] != NULL
) {
2810 delete pNode
[Index
];
2813 if (VarIdStr
[Index
] != NULL
) {
2814 delete VarIdStr
[Index
];
2820 CVfrQuestionDB::RegisterRefQuestion (
2822 IN CHAR8
*BaseVarId
,
2823 IN OUT EFI_QUESTION_ID
&QuestionId
2826 SVfrQuestionNode
*pNode
[4] = {NULL
, };
2828 CHAR8
*VarIdStr
[4] = {NULL
, };
2831 if (BaseVarId
== NULL
) {
2835 Len
= strlen (BaseVarId
);
2837 VarIdStr
[0] = new CHAR8
[Len
+ strlen (".QuestionId") + 1];
2838 if (VarIdStr
[0] != NULL
) {
2839 strcpy (VarIdStr
[0], BaseVarId
);
2840 strcat (VarIdStr
[0], ".QuestionId");
2842 VarIdStr
[1] = new CHAR8
[Len
+ strlen (".FormId") + 1];
2843 if (VarIdStr
[1] != NULL
) {
2844 strcpy (VarIdStr
[1], BaseVarId
);
2845 strcat (VarIdStr
[1], ".FormId");
2847 VarIdStr
[2] = new CHAR8
[Len
+ strlen (".FormSetGuid") + 1];
2848 if (VarIdStr
[2] != NULL
) {
2849 strcpy (VarIdStr
[2], BaseVarId
);
2850 strcat (VarIdStr
[2], ".FormSetGuid");
2852 VarIdStr
[3] = new CHAR8
[Len
+ strlen (".DevicePath") + 1];
2853 if (VarIdStr
[3] != NULL
) {
2854 strcpy (VarIdStr
[3], BaseVarId
);
2855 strcat (VarIdStr
[3], ".DevicePath");
2858 if ((pNode
[0] = new SVfrQuestionNode (Name
, VarIdStr
[0])) == NULL
) {
2861 if ((pNode
[1] = new SVfrQuestionNode (Name
, VarIdStr
[1])) == NULL
) {
2864 if ((pNode
[2] = new SVfrQuestionNode (Name
, VarIdStr
[2])) == NULL
) {
2867 if ((pNode
[3] = new SVfrQuestionNode (Name
, VarIdStr
[3])) == NULL
) {
2871 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
2872 QuestionId
= GetFreeQuestionId ();
2874 if (ChekQuestionIdFree (QuestionId
) == FALSE
) {
2877 MarkQuestionIdUsed (QuestionId
);
2880 pNode
[0]->mQuestionId
= QuestionId
;
2881 pNode
[1]->mQuestionId
= QuestionId
;
2882 pNode
[2]->mQuestionId
= QuestionId
;
2883 pNode
[3]->mQuestionId
= QuestionId
;
2884 pNode
[0]->mQtype
= QUESTION_REF
;
2885 pNode
[1]->mQtype
= QUESTION_REF
;
2886 pNode
[2]->mQtype
= QUESTION_REF
;
2887 pNode
[3]->mQtype
= QUESTION_REF
;
2888 pNode
[0]->mNext
= pNode
[1];
2889 pNode
[1]->mNext
= pNode
[2];
2890 pNode
[2]->mNext
= pNode
[3];
2891 pNode
[3]->mNext
= mQuestionList
;
2892 mQuestionList
= pNode
[0];
2894 gCFormPkg
.DoPendingAssign (VarIdStr
[0], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2895 gCFormPkg
.DoPendingAssign (VarIdStr
[1], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2896 gCFormPkg
.DoPendingAssign (VarIdStr
[2], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2897 gCFormPkg
.DoPendingAssign (VarIdStr
[3], (VOID
*)&QuestionId
, sizeof(EFI_QUESTION_ID
));
2902 for (Index
= 0; Index
< 4; Index
++) {
2903 if (pNode
[Index
] != NULL
) {
2904 delete pNode
[Index
];
2907 if (VarIdStr
[Index
] != NULL
) {
2908 delete VarIdStr
[Index
];
2914 CVfrQuestionDB::UpdateQuestionId (
2915 IN EFI_QUESTION_ID QId
,
2916 IN EFI_QUESTION_ID NewQId
2919 SVfrQuestionNode
*pNode
= NULL
;
2921 if (QId
== NewQId
) {
2923 return VFR_RETURN_SUCCESS
;
2927 // For Framework Vfr, don't check question ID conflict.
2929 if (!VfrCompatibleMode
&& ChekQuestionIdFree (NewQId
) == FALSE
) {
2930 return VFR_RETURN_REDEFINED
;
2933 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2934 if (pNode
->mQuestionId
== QId
) {
2939 if (pNode
== NULL
) {
2940 return VFR_RETURN_UNDEFINED
;
2943 MarkQuestionIdUnused (QId
);
2944 pNode
->mQuestionId
= NewQId
;
2945 MarkQuestionIdUsed (NewQId
);
2947 gCFormPkg
.DoPendingAssign (pNode
->mVarIdStr
, (VOID
*)&NewQId
, sizeof(EFI_QUESTION_ID
));
2949 return VFR_RETURN_SUCCESS
;
2953 CVfrQuestionDB::GetQuestionId (
2956 OUT EFI_QUESTION_ID
&QuestionId
,
2957 OUT UINT32
&BitMask
,
2958 OUT EFI_QUESION_TYPE
*QType
2961 SVfrQuestionNode
*pNode
;
2963 QuestionId
= EFI_QUESTION_ID_INVALID
;
2964 BitMask
= 0x00000000;
2965 if (QType
!= NULL
) {
2966 *QType
= QUESTION_NORMAL
;
2969 if ((Name
== NULL
) && (VarIdStr
== NULL
)) {
2973 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
2975 if (strcmp (pNode
->mName
, Name
) != 0) {
2980 if (VarIdStr
!= NULL
) {
2981 if (strcmp (pNode
->mVarIdStr
, VarIdStr
) != 0) {
2986 QuestionId
= pNode
->mQuestionId
;
2987 BitMask
= pNode
->mBitMask
;
2988 if (QType
!= NULL
) {
2989 *QType
= pNode
->mQtype
;
2998 CVfrQuestionDB::FindQuestion (
2999 IN EFI_QUESTION_ID QuestionId
3002 SVfrQuestionNode
*pNode
;
3004 if (QuestionId
== EFI_QUESTION_ID_INVALID
) {
3005 return VFR_RETURN_INVALID_PARAMETER
;
3008 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3009 if (pNode
->mQuestionId
== QuestionId
) {
3010 return VFR_RETURN_SUCCESS
;
3014 return VFR_RETURN_UNDEFINED
;
3018 CVfrQuestionDB::FindQuestion (
3022 SVfrQuestionNode
*pNode
;
3025 return VFR_RETURN_FATAL_ERROR
;
3028 for (pNode
= mQuestionList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
3029 if (strcmp (pNode
->mName
, Name
) == 0) {
3030 return VFR_RETURN_SUCCESS
;
3034 return VFR_RETURN_UNDEFINED
;
3037 CVfrStringDB::CVfrStringDB ()
3039 mStringFileName
= NULL
;
3042 CVfrStringDB::~CVfrStringDB ()
3044 if (mStringFileName
!= NULL
) {
3045 delete mStringFileName
;
3047 mStringFileName
= NULL
;
3052 CVfrStringDB::SetStringFileName(IN CHAR8
*StringFileName
)
3056 if (StringFileName
== NULL
) {
3060 FileLen
= strlen (StringFileName
) + 1;
3061 mStringFileName
= new CHAR8
[FileLen
];
3062 if (mStringFileName
== NULL
) {
3066 strcpy (mStringFileName
, StringFileName
);
3067 mStringFileName
[FileLen
- 1] = '\0';
3071 CVfrStringDB::GetVarStoreNameFormStringId (
3072 IN EFI_STRING_ID StringId
3075 FILE *pInFile
= NULL
;
3080 CHAR16
*UnicodeString
;
3081 CHAR8
*VarStoreName
= NULL
;
3085 CHAR8 LineBuf
[EFI_IFR_MAX_LENGTH
];
3087 EFI_HII_STRING_PACKAGE_HDR
*PkgHeader
;
3089 if (mStringFileName
== '\0' ) {
3093 if ((pInFile
= fopen (mStringFileName
, "rb")) == NULL
) {
3100 fseek (pInFile
, 0, SEEK_END
);
3101 Length
= ftell (pInFile
);
3102 fseek (pInFile
, 0, SEEK_SET
);
3107 StringPtr
= new UINT8
[Length
];
3108 if (StringPtr
== NULL
) {
3112 fread ((char *)StringPtr
, sizeof (UINT8
), Length
, pInFile
);
3115 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) StringPtr
;
3117 // Check the String package.
3119 if (PkgHeader
->Header
.Type
!= EFI_HII_PACKAGE_STRINGS
) {
3125 // Search the language, only search the "en-US".
3127 Current
= StringPtr
;
3128 while (strcmp (PkgHeader
->Language
, "en-US") != 0) {
3129 Current
+= PkgHeader
->Header
.Length
;
3130 PkgHeader
= (EFI_HII_STRING_PACKAGE_HDR
*) Current
;
3132 // If can't find "en-US" string package, just return the first string package.
3134 if (Current
- StringPtr
>= Length
) {
3135 Current
= StringPtr
;
3140 Current
+= PkgHeader
->HdrSize
;
3142 // Find the string block according the stringId.
3144 Status
= FindStringBlock(Current
, StringId
, &NameOffset
, &BlockType
);
3145 if (Status
!= EFI_SUCCESS
) {
3151 // Get varstore name according the string type.
3153 switch (BlockType
) {
3154 case EFI_HII_SIBT_STRING_SCSU
:
3155 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3156 case EFI_HII_SIBT_STRINGS_SCSU
:
3157 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3158 StringName
= (CHAR8
*)(Current
+ NameOffset
);
3159 VarStoreName
= new CHAR8
[strlen(StringName
) + 1];
3160 strcpy (VarStoreName
, StringName
);
3162 case EFI_HII_SIBT_STRING_UCS2
:
3163 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3164 case EFI_HII_SIBT_STRINGS_UCS2
:
3165 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3166 UnicodeString
= (CHAR16
*)(Current
+ NameOffset
);
3167 Length
= GetUnicodeStringTextSize ((UINT8
*)UnicodeString
) ;
3168 DestTmp
= new CHAR8
[Length
/ 2 + 1];
3169 VarStoreName
= DestTmp
;
3170 while (*UnicodeString
!= '\0') {
3171 *(DestTmp
++) = (CHAR8
) *(UnicodeString
++);
3181 return VarStoreName
;
3185 CVfrStringDB::FindStringBlock (
3186 IN UINT8
*StringData
,
3187 IN EFI_STRING_ID StringId
,
3188 OUT UINT32
*StringTextOffset
,
3189 OUT UINT8
*BlockType
3193 EFI_STRING_ID CurrentStringId
;
3196 UINT8
*StringTextPtr
;
3201 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
3205 CurrentStringId
= 1;
3208 // Parse the string blocks to get the string text and font.
3210 BlockHdr
= StringData
;
3213 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
3214 switch (*BlockHdr
) {
3215 case EFI_HII_SIBT_STRING_SCSU
:
3216 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3217 StringTextPtr
= BlockHdr
+ Offset
;
3218 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3222 case EFI_HII_SIBT_STRING_SCSU_FONT
:
3223 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3224 StringTextPtr
= BlockHdr
+ Offset
;
3225 BlockSize
+= Offset
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3229 case EFI_HII_SIBT_STRINGS_SCSU
:
3230 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3231 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
3232 BlockSize
+= StringTextPtr
- BlockHdr
;
3234 for (Index
= 0; Index
< StringCount
; Index
++) {
3235 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3236 if (CurrentStringId
== StringId
) {
3237 *BlockType
= *BlockHdr
;
3238 *StringTextOffset
= StringTextPtr
- StringData
;
3241 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3246 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
3249 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3252 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
3253 BlockSize
+= StringTextPtr
- BlockHdr
;
3255 for (Index
= 0; Index
< StringCount
; Index
++) {
3256 BlockSize
+= strlen ((CHAR8
*) StringTextPtr
) + 1;
3257 if (CurrentStringId
== StringId
) {
3258 *BlockType
= *BlockHdr
;
3259 *StringTextOffset
= StringTextPtr
- StringData
;
3262 StringTextPtr
= StringTextPtr
+ strlen ((CHAR8
*) StringTextPtr
) + 1;
3267 case EFI_HII_SIBT_STRING_UCS2
:
3268 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
3269 StringTextPtr
= BlockHdr
+ Offset
;
3271 // Use StringSize to store the size of the specified string, including the NULL
3274 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3275 BlockSize
+= Offset
+ StringSize
;
3279 case EFI_HII_SIBT_STRING_UCS2_FONT
:
3280 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3281 StringTextPtr
= BlockHdr
+ Offset
;
3283 // Use StrSize to store the size of the specified string, including the NULL
3286 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3287 BlockSize
+= Offset
+ StringSize
;
3291 case EFI_HII_SIBT_STRINGS_UCS2
:
3292 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
3293 StringTextPtr
= BlockHdr
+ Offset
;
3294 BlockSize
+= Offset
;
3295 memcpy (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3296 for (Index
= 0; Index
< StringCount
; Index
++) {
3297 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3298 BlockSize
+= StringSize
;
3299 if (CurrentStringId
== StringId
) {
3300 *BlockType
= *BlockHdr
;
3301 *StringTextOffset
= StringTextPtr
- StringData
;
3304 StringTextPtr
= StringTextPtr
+ StringSize
;
3309 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
3310 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
3311 StringTextPtr
= BlockHdr
+ Offset
;
3312 BlockSize
+= Offset
;
3315 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3318 for (Index
= 0; Index
< StringCount
; Index
++) {
3319 StringSize
= GetUnicodeStringTextSize (StringTextPtr
);
3320 BlockSize
+= StringSize
;
3321 if (CurrentStringId
== StringId
) {
3322 *BlockType
= *BlockHdr
;
3323 *StringTextOffset
= StringTextPtr
- StringData
;
3326 StringTextPtr
= StringTextPtr
+ StringSize
;
3331 case EFI_HII_SIBT_DUPLICATE
:
3332 if (CurrentStringId
== StringId
) {
3334 // Incoming StringId is an id of a duplicate string block.
3335 // Update the StringId to be the previous string block.
3336 // Go back to the header of string block to search.
3340 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
3341 sizeof (EFI_STRING_ID
)
3343 CurrentStringId
= 1;
3346 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
3351 case EFI_HII_SIBT_SKIP1
:
3352 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
3353 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3354 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
3357 case EFI_HII_SIBT_SKIP2
:
3358 memcpy (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
3359 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
3360 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
3363 case EFI_HII_SIBT_EXT1
:
3366 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3369 BlockSize
+= Length8
;
3372 case EFI_HII_SIBT_EXT2
:
3373 memcpy (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
3374 BlockSize
+= Ext2
.Length
;
3377 case EFI_HII_SIBT_EXT4
:
3380 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
3384 BlockSize
+= Length32
;
3391 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
3392 *StringTextOffset
= BlockHdr
- StringData
+ Offset
;
3393 *BlockType
= *BlockHdr
;
3395 if (StringId
== CurrentStringId
- 1) {
3397 // if only one skip item, return EFI_NOT_FOUND.
3399 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
3400 return EFI_NOT_FOUND
;
3406 if (StringId
< CurrentStringId
- 1) {
3407 return EFI_NOT_FOUND
;
3410 BlockHdr
= StringData
+ BlockSize
;
3413 return EFI_NOT_FOUND
;
3417 CVfrStringDB::GetUnicodeStringTextSize (
3424 StringSize
= sizeof (CHAR16
);
3425 StringPtr
= (UINT16
*)StringSrc
;
3426 while (*StringPtr
++ != L
'\0') {
3427 StringSize
+= sizeof (CHAR16
);
3433 BOOLEAN VfrCompatibleMode
= FALSE
;
3435 CVfrVarDataTypeDB gCVfrVarDataTypeDB
;