]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
1 /** @file
2
3 Vfr common library functions.
4
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "stdio.h"
11 #include "stdlib.h"
12 #include "assert.h"
13 #include "CommonLib.h"
14 #include "VfrUtilityLib.h"
15 #include "VfrFormPkg.h"
16
17 VOID
18 CVfrBinaryOutput::WriteLine (
19 IN FILE *pFile,
20 IN UINT32 LineBytes,
21 IN CONST CHAR8 *LineHeader,
22 IN CHAR8 *BlkBuf,
23 IN UINT32 BlkSize
24 )
25 {
26 UINT32 Index;
27
28 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
29 return;
30 }
31
32 for (Index = 0; Index < BlkSize; Index++) {
33 if ((Index % LineBytes) == 0) {
34 fprintf (pFile, "\n%s", LineHeader);
35 }
36 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
37 }
38 }
39
40 VOID
41 CVfrBinaryOutput::WriteEnd (
42 IN FILE *pFile,
43 IN UINT32 LineBytes,
44 IN CONST CHAR8 *LineHeader,
45 IN CHAR8 *BlkBuf,
46 IN UINT32 BlkSize
47 )
48 {
49 UINT32 Index;
50
51 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
52 return;
53 }
54
55 for (Index = 0; Index < BlkSize - 1; Index++) {
56 if ((Index % LineBytes) == 0) {
57 fprintf (pFile, "\n%s", LineHeader);
58 }
59 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
60 }
61
62 if ((Index % LineBytes) == 0) {
63 fprintf (pFile, "\n%s", LineHeader);
64 }
65 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
66 }
67
68 SConfigInfo::SConfigInfo (
69 IN UINT8 Type,
70 IN UINT16 Offset,
71 IN UINT32 Width,
72 IN EFI_IFR_TYPE_VALUE Value
73 )
74 {
75 mNext = NULL;
76 mOffset = Offset;
77 mWidth = (UINT16)Width;
78 mValue = new UINT8[mWidth];
79 if (mValue == NULL) {
80 return;
81 }
82
83 switch (Type) {
84 case EFI_IFR_TYPE_NUM_SIZE_8 :
85 memcpy (mValue, &Value.u8, mWidth);
86 break;
87 case EFI_IFR_TYPE_NUM_SIZE_16 :
88 memcpy (mValue, &Value.u16, mWidth);
89 break;
90 case EFI_IFR_TYPE_NUM_SIZE_32 :
91 memcpy (mValue, &Value.u32, mWidth);
92 break;
93 case EFI_IFR_TYPE_NUM_SIZE_64 :
94 memcpy (mValue, &Value.u64, mWidth);
95 break;
96 case EFI_IFR_TYPE_BOOLEAN :
97 memcpy (mValue, &Value.b, mWidth);
98 break;
99 case EFI_IFR_TYPE_TIME :
100 memcpy (mValue, &Value.time, mWidth);
101 break;
102 case EFI_IFR_TYPE_DATE :
103 memcpy (mValue, &Value.date, mWidth);
104 break;
105 case EFI_IFR_TYPE_STRING :
106 memcpy (mValue, &Value.string, mWidth);
107 break;
108 case EFI_IFR_TYPE_BUFFER :
109 memcpy (mValue, &Value.u8, mWidth);
110 break;
111
112 case EFI_IFR_TYPE_OTHER :
113 return;
114 }
115 }
116
117 SConfigInfo::~SConfigInfo (
118 VOID
119 )
120 {
121 ARRAY_SAFE_FREE (mValue);
122 }
123
124 SConfigItem::SConfigItem (
125 IN CHAR8 *Name,
126 IN EFI_GUID *Guid,
127 IN CHAR8 *Id
128 )
129 {
130 mName = NULL;
131 mGuid = NULL;
132 mId = NULL;
133 mInfoStrList = NULL;
134 mNext = NULL;
135
136 if (Name != NULL) {
137 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
138 strcpy (mName, Name);
139 }
140 }
141
142 if (Guid != NULL) {
143 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
144 memcpy (mGuid, Guid, sizeof (EFI_GUID));
145 }
146 }
147
148 if (Id != NULL) {
149 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
150 strcpy (mId, Id);
151 }
152 }
153 }
154
155 SConfigItem::SConfigItem (
156 IN CHAR8 *Name,
157 IN EFI_GUID *Guid,
158 IN CHAR8 *Id,
159 IN UINT8 Type,
160 IN UINT16 Offset,
161 IN UINT16 Width,
162 IN EFI_IFR_TYPE_VALUE Value
163 )
164 {
165 mName = NULL;
166 mGuid = NULL;
167 mId = NULL;
168 mInfoStrList = NULL;
169 mNext = NULL;
170
171 if (Name != NULL) {
172 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
173 strcpy (mName, Name);
174 }
175 }
176
177 if (Guid != NULL) {
178 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
179 memcpy (mGuid, Guid, sizeof (EFI_GUID));
180 }
181 }
182
183 if (Id != NULL) {
184 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
185 strcpy (mId, Id);
186 }
187 }
188
189 mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
190 }
191
192 SConfigItem::~SConfigItem (
193 VOID
194 )
195 {
196 SConfigInfo *Info;
197
198 ARRAY_SAFE_FREE (mName);
199 ARRAY_SAFE_FREE (mGuid);
200 ARRAY_SAFE_FREE (mId);
201 while (mInfoStrList != NULL) {
202 Info = mInfoStrList;
203 mInfoStrList = mInfoStrList->mNext;
204
205 BUFFER_SAFE_FREE (Info);
206 }
207 }
208
209 UINT8
210 CVfrBufferConfig::Register (
211 IN CHAR8 *Name,
212 IN EFI_GUID *Guid,
213 IN CHAR8 *Id
214 )
215 {
216 SConfigItem *pNew;
217
218 if (Select (Name, Guid) == 0) {
219 return 1;
220 }
221
222 if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {
223 return 2;
224 }
225
226 if (mItemListHead == NULL) {
227 mItemListHead = pNew;
228 mItemListTail = pNew;
229 } else {
230 mItemListTail->mNext = pNew;
231 mItemListTail = pNew;
232 }
233 mItemListPos = pNew;
234
235 return 0;
236 }
237
238 VOID
239 CVfrBufferConfig::Open (
240 VOID
241 )
242 {
243 mItemListPos = mItemListHead;
244 }
245
246 BOOLEAN
247 CVfrBufferConfig::Eof(
248 VOID
249 )
250 {
251 return (mItemListPos == NULL) ? TRUE : FALSE;
252 }
253
254 UINT8
255 CVfrBufferConfig::Select (
256 IN CHAR8 *Name,
257 IN EFI_GUID *Guid,
258 IN CHAR8 *Id
259 )
260 {
261 SConfigItem *p;
262
263 if (Name == NULL || Guid == NULL) {
264 mItemListPos = mItemListHead;
265 return 0;
266 } else {
267 for (p = mItemListHead; p != NULL; p = p->mNext) {
268 if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {
269 continue;
270 }
271
272 if (Id != NULL) {
273 if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
274 continue;
275 }
276 } else if (p->mId != NULL) {
277 continue;
278 }
279
280 mItemListPos = p;
281 return 0;
282 }
283 }
284
285 return 1;
286 }
287
288 UINT8
289 CVfrBufferConfig::Write (
290 IN CONST CHAR8 Mode,
291 IN CHAR8 *Name,
292 IN EFI_GUID *Guid,
293 IN CHAR8 *Id,
294 IN UINT8 Type,
295 IN UINT16 Offset,
296 IN UINT32 Width,
297 IN EFI_IFR_TYPE_VALUE Value
298 )
299 {
300 UINT8 Ret;
301 SConfigItem *pItem;
302 SConfigInfo *pInfo;
303
304 if ((Ret = Select (Name, Guid)) != 0) {
305 return Ret;
306 }
307
308 switch (Mode) {
309 case 'a' : // add
310 if (Select (Name, Guid, Id) != 0) {
311 if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {
312 return 2;
313 }
314 if (mItemListHead == NULL) {
315 mItemListHead = pItem;
316 mItemListTail = pItem;
317 } else {
318 mItemListTail->mNext = pItem;
319 mItemListTail = pItem;
320 }
321 mItemListPos = pItem;
322 } else {
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) {
326 return 0;
327 }
328 }
329 if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
330 return 2;
331 }
332 pInfo->mNext = mItemListPos->mInfoStrList;
333 mItemListPos->mInfoStrList = pInfo;
334 }
335 break;
336
337 case 'd' : // delete
338 if (mItemListHead == mItemListPos) {
339 mItemListHead = mItemListPos->mNext;
340 delete mItemListPos;
341 break;
342 }
343
344 for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
345 ;
346
347 pItem->mNext = mItemListPos->mNext;
348 if (mItemListTail == mItemListPos) {
349 mItemListTail = pItem;
350 }
351 delete mItemListPos;
352 mItemListPos = pItem->mNext;
353 break;
354
355 case 'i' : // set info
356 if (mItemListPos->mId != NULL) {
357 delete[] mItemListPos->mId;
358 }
359 mItemListPos->mId = NULL;
360 if (Id != NULL) {
361 if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
362 return 2;
363 }
364 strcpy (mItemListPos->mId, Id);
365 }
366 break;
367
368 default :
369 return 1;
370 }
371
372 return 0;
373 }
374
375
376 VOID
377 CVfrBufferConfig::Close (
378 VOID
379 )
380 {
381 mItemListPos = NULL;
382 }
383
384 #define BYTES_PRE_LINE 0x10
385
386 VOID
387 CVfrBufferConfig::OutputCFile (
388 IN FILE *pFile,
389 IN CHAR8 *BaseName
390 )
391 {
392 CVfrBinaryOutput Output;
393 SConfigItem *Item;
394 SConfigInfo *Info;
395 UINT32 TotalLen;
396
397 if (pFile == NULL) {
398 return;
399 }
400
401 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
402 if (Item->mId != NULL || Item->mInfoStrList == NULL) {
403 continue;
404 }
405 fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
406
407 TotalLen = sizeof (UINT32);
408 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
409 TotalLen += sizeof (UINT16) * 2;
410 }
411 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
412
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));
417 }
418 fprintf (pFile, "\n};\n");
419 }
420
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);
424
425 TotalLen = sizeof (UINT32);
426 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
427 TotalLen += Info->mWidth + sizeof (UINT16) * 2;
428 }
429 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
430
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);
437 } else {
438 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
439 }
440 }
441 fprintf (pFile, "\n};\n");
442 }
443 }
444 }
445
446 CVfrBufferConfig::CVfrBufferConfig (
447 VOID
448 )
449 {
450 mItemListHead = NULL;
451 mItemListTail = NULL;
452 mItemListPos = NULL;
453 }
454
455 CVfrBufferConfig::~CVfrBufferConfig (
456 VOID
457 )
458 {
459 SConfigItem *p;
460
461 while (mItemListHead != NULL) {
462 p = mItemListHead;
463 mItemListHead = mItemListHead->mNext;
464 delete p;
465 }
466
467 mItemListHead = NULL;
468 mItemListTail = NULL;
469 mItemListPos = NULL;
470 }
471
472 CVfrBufferConfig gCVfrBufferConfig;
473
474 static struct {
475 CONST CHAR8 *mTypeName;
476 UINT8 mType;
477 UINT32 mSize;
478 UINT32 mAlign;
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}
490 };
491
492 STATIC
493 BOOLEAN
494 _IS_INTERNAL_TYPE (
495 IN CHAR8 *TypeName
496 )
497 {
498 UINT32 Index;
499
500 if (TypeName == NULL) {
501 return FALSE;
502 }
503
504 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
505 if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
506 return TRUE;
507 }
508 }
509
510 return FALSE;
511 }
512
513 STATIC
514 CHAR8 *
515 TrimHex (
516 IN CHAR8 *Str,
517 OUT bool *IsHex
518 )
519 {
520 *IsHex = FALSE;
521
522 while (*Str && *Str == ' ') {
523 Str++;
524 }
525 while (*Str && *Str == '0') {
526 Str++;
527 }
528 if (*Str && (*Str == 'x' || *Str == 'X')) {
529 Str++;
530 *IsHex = TRUE;
531 }
532
533 return Str;
534 }
535
536 UINT32
537 _STR2U32 (
538 IN CHAR8 *Str
539 )
540 {
541 bool IsHex;
542 UINT32 Value;
543 CHAR8 c;
544
545 Str = TrimHex (Str, &IsHex);
546 for (Value = 0; (c = *Str) != '\0'; Str++) {
547 //
548 // BUG: does not handle overflow here
549 //
550 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
551
552 if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
553 Value += (c - 'a' + 10);
554 }
555 if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
556 Value += (c - 'A' + 10);
557 }
558 if (c >= '0' && c <= '9') {
559 Value += (c - '0');
560 }
561 }
562
563 return Value;
564 }
565
566 VOID
567 CVfrVarDataTypeDB::RegisterNewType (
568 IN SVfrDataType *New
569 )
570 {
571 New->mNext = mDataTypeList;
572 mDataTypeList = New;
573 }
574
575 EFI_VFR_RETURN_CODE
576 CVfrVarDataTypeDB::ExtractStructTypeName (
577 IN CHAR8 *&VarStr,
578 OUT CHAR8 *TName
579 )
580 {
581 if (TName == NULL) {
582 return VFR_RETURN_FATAL_ERROR;
583 }
584
585 while((*VarStr != '\0') && (*VarStr != '.')) {
586 *TName = *VarStr;
587 VarStr++;
588 TName++;
589 }
590 *TName = '\0';
591 if (*VarStr == '.') {
592 VarStr++;
593 }
594
595 return VFR_RETURN_SUCCESS;
596 }
597
598 /**
599 Check whether the DataType contain bit field.
600
601 @param TypeName The name of the type.
602
603 **/
604 BOOLEAN
605 CVfrVarDataTypeDB::DataTypeHasBitField (
606 IN CHAR8 *TypeName
607 )
608 {
609 SVfrDataType *pType = NULL;
610 SVfrDataField *pTmp;
611
612 GetDataType (TypeName, &pType);
613
614 if (pType == NULL){
615 return FALSE;
616 }
617 for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {
618 if (pTmp->mIsBitField) {
619 return TRUE;
620 }
621 }
622 return FALSE;
623 }
624
625 /**
626 Check whether the field is bit field or not.
627
628 @param VarStr Point to the field name which may contain the structure name.
629
630 **/
631 BOOLEAN
632 CVfrVarDataTypeDB::IsThisBitField (
633 IN CHAR8 *VarStr
634 )
635 {
636 CHAR8 FName[MAX_NAME_LEN];
637 CHAR8 TName[MAX_NAME_LEN];
638 UINT32 ArrayIdx;
639 SVfrDataType *pType = NULL;
640 SVfrDataField *pField = NULL;
641
642 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
643 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
644
645 while (*VarStr != '\0') {
646 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
647 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
648 pType = pField->mFieldType;
649 }
650 if (pField != NULL && pField->mIsBitField) {
651 return TRUE;
652 } else {
653 return FALSE;
654 }
655 }
656
657 EFI_VFR_RETURN_CODE
658 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
659 IN CHAR8 *&VarStr,
660 IN CHAR8 *FName,
661 OUT UINT32 &ArrayIdx
662 )
663 {
664 UINT32 Idx;
665 CHAR8 ArrayStr[MAX_NAME_LEN + 1];
666
667 ArrayIdx = INVALID_ARRAY_INDEX;
668
669 if (FName == NULL) {
670 return VFR_RETURN_FATAL_ERROR;
671 }
672
673 while((*VarStr != '\0') &&
674 (*VarStr != '.') &&
675 (*VarStr != '[') &&
676 (*VarStr != ']')) {
677 *FName = *VarStr;
678 VarStr++;
679 FName++;
680 }
681 *FName = '\0';
682
683 switch (*VarStr) {
684 case '.' :
685 VarStr++;
686 case '\0':
687 return VFR_RETURN_SUCCESS;
688 case '[' :
689 VarStr++;
690 for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
691 ArrayStr[Idx] = *VarStr;
692 }
693 ArrayStr[Idx] = '\0';
694
695 if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
696 return VFR_RETURN_DATA_STRING_ERROR;
697 }
698 ArrayIdx = _STR2U32 (ArrayStr);
699 if (*VarStr == ']') {
700 VarStr++;
701 }
702 if (*VarStr == '.') {
703 VarStr++;
704 }
705 return VFR_RETURN_SUCCESS;
706 case ']':
707 return VFR_RETURN_DATA_STRING_ERROR;
708 }
709
710 return VFR_RETURN_SUCCESS;
711 }
712
713 EFI_VFR_RETURN_CODE
714 CVfrVarDataTypeDB::GetTypeField (
715 IN CONST CHAR8 *FName,
716 IN SVfrDataType *Type,
717 OUT SVfrDataField *&Field
718 )
719 {
720 SVfrDataField *pField = NULL;
721
722 if ((FName == NULL) || (Type == NULL)) {
723 return VFR_RETURN_FATAL_ERROR;
724 }
725
726 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
727 //
728 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
729 // add code to adjust it.
730 //
731 if (Type->mType == EFI_IFR_TYPE_TIME) {
732 if (strcmp (FName, "Hour") == 0) {
733 FName = "Hours";
734 } else if (strcmp (FName, "Minute") == 0) {
735 FName = "Minuts";
736 } else if (strcmp (FName, "Second") == 0) {
737 FName = "Seconds";
738 }
739 }
740
741 if (strcmp (pField->mFieldName, FName) == 0) {
742 Field = pField;
743 return VFR_RETURN_SUCCESS;
744 }
745 }
746
747 return VFR_RETURN_UNDEFINED;
748 }
749
750 EFI_VFR_RETURN_CODE
751 CVfrVarDataTypeDB::GetFieldOffset (
752 IN SVfrDataField *Field,
753 IN UINT32 ArrayIdx,
754 OUT UINT32 &Offset,
755 IN BOOLEAN IsBitField
756 )
757 {
758 if (Field == NULL) {
759 return VFR_RETURN_FATAL_ERROR;
760 }
761
762 //
763 // Framework Vfr file Array Index is from 1.
764 // But Uefi Vfr file Array Index is from 0.
765 //
766 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
767 if (ArrayIdx == 0) {
768 return VFR_RETURN_ERROR_ARRARY_NUM;
769 }
770 ArrayIdx = ArrayIdx - 1;
771 }
772
773 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
774 return VFR_RETURN_ERROR_ARRARY_NUM;
775 }
776
777 //
778 // Be compatible with the current usage
779 // If ArraryIdx is not specified, the first one is used.
780 //
781 // if ArrayNum is larger than zero, ArraryIdx must be specified.
782 //
783 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
784 // return VFR_RETURN_ERROR_ARRARY_NUM;
785 // }
786 //
787 if (IsBitField) {
788 Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;
789 } else {
790 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
791 }
792 return VFR_RETURN_SUCCESS;
793 }
794
795 UINT8
796 CVfrVarDataTypeDB::GetFieldWidth (
797 IN SVfrDataField *Field
798 )
799 {
800 if (Field == NULL) {
801 return 0;
802 }
803
804 return Field->mFieldType->mType;
805 }
806
807 UINT32
808 CVfrVarDataTypeDB::GetFieldSize (
809 IN SVfrDataField *Field,
810 IN UINT32 ArrayIdx,
811 IN BOOLEAN BitField
812 )
813 {
814 if (Field == NULL) {
815 return VFR_RETURN_FATAL_ERROR;
816 }
817
818 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
819 return Field->mFieldType->mTotalSize * Field->mArrayNum;
820 } else {
821 if (BitField) {
822 return Field->mBitWidth;
823 } else {
824 return Field->mFieldType->mTotalSize;
825 }
826 }
827 }
828
829 VOID
830 CVfrVarDataTypeDB::InternalTypesListInit (
831 VOID
832 )
833 {
834 SVfrDataType *New = NULL;
835 UINT32 Index;
836
837 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
838 New = new SVfrDataType;
839 if (New != NULL) {
840 assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN);
841 strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1);
842 New->mTypeName[MAX_NAME_LEN - 1] = 0;
843 New->mType = gInternalTypesTable[Index].mType;
844 New->mAlign = gInternalTypesTable[Index].mAlign;
845 New->mTotalSize = gInternalTypesTable[Index].mSize;
846 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
847 SVfrDataField *pYearField = new SVfrDataField;
848 SVfrDataField *pMonthField = new SVfrDataField;
849 SVfrDataField *pDayField = new SVfrDataField;
850
851 strcpy (pYearField->mFieldName, "Year");
852 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
853 pYearField->mOffset = 0;
854 pYearField->mNext = pMonthField;
855 pYearField->mArrayNum = 0;
856 pYearField->mIsBitField = FALSE;
857
858 strcpy (pMonthField->mFieldName, "Month");
859 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
860 pMonthField->mOffset = 2;
861 pMonthField->mNext = pDayField;
862 pMonthField->mArrayNum = 0;
863 pMonthField->mIsBitField = FALSE;
864
865 strcpy (pDayField->mFieldName, "Day");
866 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
867 pDayField->mOffset = 3;
868 pDayField->mNext = NULL;
869 pDayField->mArrayNum = 0;
870 pDayField->mIsBitField = FALSE;
871
872 New->mMembers = pYearField;
873 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
874 SVfrDataField *pHoursField = new SVfrDataField;
875 SVfrDataField *pMinutesField = new SVfrDataField;
876 SVfrDataField *pSecondsField = new SVfrDataField;
877
878 strcpy (pHoursField->mFieldName, "Hours");
879 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
880 pHoursField->mOffset = 0;
881 pHoursField->mNext = pMinutesField;
882 pHoursField->mArrayNum = 0;
883 pHoursField->mIsBitField = FALSE;
884
885 strcpy (pMinutesField->mFieldName, "Minutes");
886 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
887 pMinutesField->mOffset = 1;
888 pMinutesField->mNext = pSecondsField;
889 pMinutesField->mArrayNum = 0;
890 pMinutesField->mIsBitField = FALSE;
891
892 strcpy (pSecondsField->mFieldName, "Seconds");
893 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
894 pSecondsField->mOffset = 2;
895 pSecondsField->mNext = NULL;
896 pSecondsField->mArrayNum = 0;
897 pSecondsField->mIsBitField = FALSE;
898
899 New->mMembers = pHoursField;
900 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
901 SVfrDataField *pQuestionIdField = new SVfrDataField;
902 SVfrDataField *pFormIdField = new SVfrDataField;
903 SVfrDataField *pFormSetGuidField = new SVfrDataField;
904 SVfrDataField *pDevicePathField = new SVfrDataField;
905
906 strcpy (pQuestionIdField->mFieldName, "QuestionId");
907 GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
908 pQuestionIdField->mOffset = 0;
909 pQuestionIdField->mNext = pFormIdField;
910 pQuestionIdField->mArrayNum = 0;
911 pQuestionIdField->mIsBitField = FALSE;
912
913 strcpy (pFormIdField->mFieldName, "FormId");
914 GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
915 pFormIdField->mOffset = 2;
916 pFormIdField->mNext = pFormSetGuidField;
917 pFormIdField->mArrayNum = 0;
918 pFormIdField->mIsBitField = FALSE;
919
920 strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
921 GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
922 pFormSetGuidField->mOffset = 4;
923 pFormSetGuidField->mNext = pDevicePathField;
924 pFormSetGuidField->mArrayNum = 0;
925 pFormSetGuidField->mIsBitField = FALSE;
926
927 strcpy (pDevicePathField->mFieldName, "DevicePath");
928 GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
929 pDevicePathField->mOffset = 20;
930 pDevicePathField->mNext = NULL;
931 pDevicePathField->mArrayNum = 0;
932 pDevicePathField->mIsBitField = FALSE;
933
934 New->mMembers = pQuestionIdField;
935 } else {
936 New->mMembers = NULL;
937 }
938 New->mNext = NULL;
939 RegisterNewType (New);
940 New = NULL;
941 }
942 }
943 }
944
945 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
946 VOID
947 )
948 {
949 mDataTypeList = NULL;
950 mNewDataType = NULL;
951 mCurrDataField = NULL;
952 mPackAlign = DEFAULT_PACK_ALIGN;
953 mPackStack = NULL;
954 mFirstNewDataTypeName = NULL;
955 mCurrDataType = NULL;
956
957 InternalTypesListInit ();
958 }
959
960 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
961 VOID
962 )
963 {
964 SVfrDataType *pType;
965 SVfrDataField *pField;
966 SVfrPackStackNode *pPack;
967
968 if (mNewDataType != NULL) {
969 delete mNewDataType;
970 }
971
972 while (mDataTypeList != NULL) {
973 pType = mDataTypeList;
974 mDataTypeList = mDataTypeList->mNext;
975 while(pType->mMembers != NULL) {
976 pField = pType->mMembers;
977 pType->mMembers = pType->mMembers->mNext;
978 delete pField;
979 }
980 delete pType;
981 }
982
983 while (mPackStack != NULL) {
984 pPack = mPackStack;
985 mPackStack = mPackStack->mNext;
986 delete pPack;
987 }
988 }
989
990 EFI_VFR_RETURN_CODE
991 CVfrVarDataTypeDB::Pack (
992 IN UINT32 LineNum,
993 IN UINT8 Action,
994 IN CHAR8 *Identifier,
995 IN UINT32 Number
996 )
997 {
998 UINT32 PackAlign;
999 CHAR8 Msg[MAX_STRING_LEN] = {0, };
1000
1001 if (Action & VFR_PACK_SHOW) {
1002 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
1003 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
1004 }
1005
1006 if (Action & VFR_PACK_PUSH) {
1007 SVfrPackStackNode *pNew = NULL;
1008
1009 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
1010 return VFR_RETURN_FATAL_ERROR;
1011 }
1012 pNew->mNext = mPackStack;
1013 mPackStack = pNew;
1014 }
1015
1016 if (Action & VFR_PACK_POP) {
1017 SVfrPackStackNode *pNode = NULL;
1018
1019 if (mPackStack == NULL) {
1020 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
1021 }
1022
1023 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
1024 if (pNode->Match (Identifier) == TRUE) {
1025 mPackAlign = pNode->mNumber;
1026 mPackStack = pNode->mNext;
1027 }
1028 }
1029 }
1030
1031 if (Action & VFR_PACK_ASSIGN) {
1032 PackAlign = (Number > 1) ? Number + Number % 2 : Number;
1033 if ((PackAlign == 0) || (PackAlign > 16)) {
1034 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
1035 } else {
1036 mPackAlign = PackAlign;
1037 }
1038 }
1039
1040 return VFR_RETURN_SUCCESS;
1041 }
1042
1043 VOID
1044 CVfrVarDataTypeDB::DeclareDataTypeBegin (
1045 VOID
1046 )
1047 {
1048 SVfrDataType *pNewType = NULL;
1049
1050 pNewType = new SVfrDataType;
1051 pNewType->mTypeName[0] = '\0';
1052 pNewType->mType = EFI_IFR_TYPE_OTHER;
1053 pNewType->mAlign = DEFAULT_ALIGN;
1054 pNewType->mTotalSize = 0;
1055 pNewType->mMembers = NULL;
1056 pNewType->mNext = NULL;
1057 pNewType->mHasBitField = FALSE;
1058
1059 mNewDataType = pNewType;
1060 }
1061
1062 EFI_VFR_RETURN_CODE
1063 CVfrVarDataTypeDB::SetNewTypeName (
1064 IN CHAR8 *TypeName
1065 )
1066 {
1067 SVfrDataType *pType;
1068
1069 if (mNewDataType == NULL) {
1070 return VFR_RETURN_ERROR_SKIPED;
1071 }
1072 if (TypeName == NULL) {
1073 return VFR_RETURN_FATAL_ERROR;
1074 }
1075 if (strlen(TypeName) >= MAX_NAME_LEN) {
1076 return VFR_RETURN_INVALID_PARAMETER;
1077 }
1078
1079 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1080 if (strcmp(pType->mTypeName, TypeName) == 0) {
1081 return VFR_RETURN_REDEFINED;
1082 }
1083 }
1084
1085 strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);
1086 mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;
1087 return VFR_RETURN_SUCCESS;
1088 }
1089
1090 /**
1091 Record the bit field info in the data type.
1092
1093 @param FieldName Point to the field name.
1094 @param TypeName Point to the type name.
1095 @param Width The bit width.
1096 @param FieldInUnion The filed is in Union type or Structure type.
1097
1098 **/
1099 EFI_VFR_RETURN_CODE
1100 CVfrVarDataTypeDB::DataTypeAddBitField (
1101 IN CHAR8 *FieldName,
1102 IN CHAR8 *TypeName,
1103 IN UINT32 Width,
1104 IN BOOLEAN FieldInUnion
1105 )
1106 {
1107 SVfrDataField *pNewField = NULL;
1108 SVfrDataType *pFieldType = NULL;
1109 SVfrDataField *pTmp;
1110 UINT32 Align;
1111 UINT32 MaxDataTypeSize;
1112 BOOLEAN UpdateTotalSize;
1113
1114 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
1115
1116 if (Width > MAX_BIT_WIDTH) {
1117 return VFR_RETURN_BIT_WIDTH_ERROR;
1118 }
1119
1120 if (Width > pFieldType->mTotalSize * 8) {
1121 return VFR_RETURN_BIT_WIDTH_ERROR;
1122 }
1123
1124 if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {
1125 return VFR_RETURN_INVALID_PARAMETER;
1126 }
1127
1128 if (Width == 0 && FieldName != NULL) {
1129 return VFR_RETURN_INVALID_PARAMETER;
1130 }
1131
1132 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
1133 if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {
1134 return VFR_RETURN_REDEFINED;
1135 }
1136 }
1137
1138 Align = MIN (mPackAlign, pFieldType->mAlign);
1139 UpdateTotalSize = FALSE;
1140
1141 if ((pNewField = new SVfrDataField) == NULL) {
1142 return VFR_RETURN_OUT_FOR_RESOURCES;
1143 }
1144
1145 MaxDataTypeSize = mNewDataType->mTotalSize;
1146 if (FieldName != NULL) {
1147 strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
1148 pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
1149 }
1150 pNewField->mFieldType = pFieldType;
1151 pNewField->mIsBitField = TRUE;
1152 pNewField->mBitWidth = Width;
1153 pNewField->mArrayNum = 0;
1154 pNewField->mBitOffset = 0;
1155 pNewField->mOffset = 0;
1156
1157 if (mNewDataType->mMembers == NULL) {
1158 mNewDataType->mMembers = pNewField;
1159 pNewField->mNext = NULL;
1160 } else {
1161 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
1162 ;
1163 pTmp->mNext = pNewField;
1164 pNewField->mNext = NULL;
1165 }
1166
1167 if (FieldInUnion) {
1168 pNewField->mOffset = 0;
1169 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
1170 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
1171 }
1172 } else {
1173 //
1174 // Check whether the bit fields can be contained within one FieldType.
1175 //
1176 if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&
1177 (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {
1178 pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;
1179 pNewField->mOffset = pTmp->mOffset;
1180 //
1181 // If BitWidth=0,used to force alignment at the next word boundary.
1182 // So make this bit field occupy the remaing bit width of current field type.
1183 //
1184 if (pNewField->mBitWidth == 0) {
1185 pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);
1186 }
1187 } else {
1188 //
1189 // The bit filed start a new memory
1190 //
1191 pNewField->mBitOffset = mNewDataType->mTotalSize * 8;
1192 UpdateTotalSize = TRUE;
1193 }
1194 }
1195
1196 if (UpdateTotalSize){
1197 if ((mNewDataType->mTotalSize % Align) == 0) {
1198 pNewField->mOffset = mNewDataType->mTotalSize;
1199 } else {
1200 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
1201 }
1202 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);
1203 }
1204
1205 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
1206 mNewDataType->mHasBitField = TRUE;
1207 return VFR_RETURN_SUCCESS;
1208 }
1209
1210 EFI_VFR_RETURN_CODE
1211 CVfrVarDataTypeDB::DataTypeAddField (
1212 IN CHAR8 *FieldName,
1213 IN CHAR8 *TypeName,
1214 IN UINT32 ArrayNum,
1215 IN BOOLEAN FieldInUnion
1216 )
1217 {
1218 SVfrDataField *pNewField = NULL;
1219 SVfrDataType *pFieldType = NULL;
1220 SVfrDataField *pTmp;
1221 UINT32 Align;
1222 UINT32 MaxDataTypeSize;
1223
1224 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
1225 MaxDataTypeSize = mNewDataType->mTotalSize;
1226
1227 if (strlen (FieldName) >= MAX_NAME_LEN) {
1228 return VFR_RETURN_INVALID_PARAMETER;
1229 }
1230
1231 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
1232 if (strcmp (pTmp->mFieldName, FieldName) == 0) {
1233 return VFR_RETURN_REDEFINED;
1234 }
1235 }
1236
1237 Align = MIN (mPackAlign, pFieldType->mAlign);
1238
1239 if ((pNewField = new SVfrDataField) == NULL) {
1240 return VFR_RETURN_OUT_FOR_RESOURCES;
1241 }
1242 strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
1243 pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
1244 pNewField->mFieldType = pFieldType;
1245 pNewField->mArrayNum = ArrayNum;
1246 pNewField->mIsBitField = FALSE;
1247 if ((mNewDataType->mTotalSize % Align) == 0) {
1248 pNewField->mOffset = mNewDataType->mTotalSize;
1249 } else {
1250 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
1251 }
1252 if (mNewDataType->mMembers == NULL) {
1253 mNewDataType->mMembers = pNewField;
1254 pNewField->mNext = NULL;
1255 } else {
1256 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
1257 ;
1258 pTmp->mNext = pNewField;
1259 pNewField->mNext = NULL;
1260 }
1261
1262 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
1263
1264 if (FieldInUnion) {
1265 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
1266 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
1267 }
1268 pNewField->mOffset = 0;
1269 } else {
1270 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
1271 }
1272
1273 return VFR_RETURN_SUCCESS;
1274 }
1275
1276 VOID
1277 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1278 VOID
1279 )
1280 {
1281 if (mNewDataType->mTypeName[0] == '\0') {
1282 return;
1283 }
1284
1285 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
1286 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
1287 }
1288
1289 RegisterNewType (mNewDataType);
1290 if (mFirstNewDataTypeName == NULL) {
1291 mFirstNewDataTypeName = mNewDataType->mTypeName;
1292 }
1293
1294 mNewDataType = NULL;
1295 }
1296
1297 EFI_VFR_RETURN_CODE
1298 CVfrVarDataTypeDB::GetDataType (
1299 IN CHAR8 *TypeName,
1300 OUT SVfrDataType **DataType
1301 )
1302 {
1303 SVfrDataType *pDataType = NULL;
1304
1305 if (TypeName == NULL) {
1306 return VFR_RETURN_ERROR_SKIPED;
1307 }
1308
1309 if (DataType == NULL) {
1310 return VFR_RETURN_FATAL_ERROR;
1311 }
1312
1313 *DataType = NULL;
1314
1315 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1316 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1317 *DataType = pDataType;
1318 return VFR_RETURN_SUCCESS;
1319 }
1320 }
1321
1322 return VFR_RETURN_UNDEFINED;
1323 }
1324
1325 EFI_VFR_RETURN_CODE
1326 CVfrVarDataTypeDB::GetDataTypeSize (
1327 IN UINT8 DataType,
1328 OUT UINT32 *Size
1329 )
1330 {
1331 SVfrDataType *pDataType = NULL;
1332
1333 if (Size == NULL) {
1334 return VFR_RETURN_FATAL_ERROR;
1335 }
1336
1337 *Size = 0;
1338 DataType = DataType & 0x0F;
1339
1340 //
1341 // For user defined data type, the size can't be got by this function.
1342 //
1343 if (DataType == EFI_IFR_TYPE_OTHER) {
1344 return VFR_RETURN_SUCCESS;
1345 }
1346
1347 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1348 if (DataType == pDataType->mType) {
1349 *Size = pDataType->mTotalSize;
1350 return VFR_RETURN_SUCCESS;
1351 }
1352 }
1353
1354 return VFR_RETURN_UNDEFINED;
1355 }
1356
1357 EFI_VFR_RETURN_CODE
1358 CVfrVarDataTypeDB::GetDataTypeSize (
1359 IN CHAR8 *TypeName,
1360 OUT UINT32 *Size
1361 )
1362 {
1363 SVfrDataType *pDataType = NULL;
1364
1365 if (Size == NULL) {
1366 return VFR_RETURN_FATAL_ERROR;
1367 }
1368
1369 *Size = 0;
1370
1371 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1372 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1373 *Size = pDataType->mTotalSize;
1374 return VFR_RETURN_SUCCESS;
1375 }
1376 }
1377
1378 return VFR_RETURN_UNDEFINED;
1379 }
1380
1381 EFI_VFR_RETURN_CODE
1382 CVfrVarDataTypeDB::GetDataFieldInfo (
1383 IN CHAR8 *VarStr,
1384 OUT UINT16 &Offset,
1385 OUT UINT8 &Type,
1386 OUT UINT32 &Size,
1387 OUT BOOLEAN &BitField
1388 )
1389 {
1390 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
1391 UINT32 ArrayIdx, Tmp;
1392 SVfrDataType *pType = NULL;
1393 SVfrDataField *pField = NULL;
1394 CHAR8 *VarStrName;
1395
1396 Offset = 0;
1397 Type = EFI_IFR_TYPE_OTHER;
1398 Size = 0;
1399 VarStrName = VarStr;
1400
1401 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
1402 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
1403
1404 BitField = IsThisBitField (VarStrName);
1405
1406 //
1407 // if it is not struct data type
1408 //
1409 Type = pType->mType;
1410 Size = pType->mTotalSize;
1411
1412 while (*VarStr != '\0') {
1413 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
1414 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
1415 pType = pField->mFieldType;
1416 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);
1417 if (BitField && !pField->mIsBitField) {
1418 Offset = (UINT16) (Offset + Tmp * 8);
1419 } else {
1420 Offset = (UINT16) (Offset + Tmp);
1421 }
1422 Type = GetFieldWidth (pField);
1423 Size = GetFieldSize (pField, ArrayIdx, BitField);
1424 }
1425 return VFR_RETURN_SUCCESS;
1426 }
1427
1428 EFI_VFR_RETURN_CODE
1429 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1430 OUT CHAR8 ***NameList,
1431 OUT UINT32 *ListSize
1432 )
1433 {
1434 UINT32 Index;
1435 SVfrDataType *pType;
1436
1437 if ((NameList == NULL) || (ListSize == NULL)) {
1438 return VFR_RETURN_FATAL_ERROR;
1439 }
1440
1441 *NameList = NULL;
1442 *ListSize = 0;
1443
1444 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1445 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1446 (*ListSize)++;
1447 }
1448 }
1449
1450 if (*ListSize == 0) {
1451 return VFR_RETURN_SUCCESS;
1452 }
1453
1454 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
1455 *ListSize = 0;
1456 return VFR_RETURN_OUT_FOR_RESOURCES;
1457 }
1458
1459 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
1460 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1461 (*NameList)[Index] = pType->mTypeName;
1462 }
1463 }
1464 return VFR_RETURN_SUCCESS;
1465 }
1466
1467 BOOLEAN
1468 CVfrVarDataTypeDB::IsTypeNameDefined (
1469 IN CHAR8 *TypeName
1470 )
1471 {
1472 SVfrDataType *pType;
1473
1474 if (TypeName == NULL) {
1475 return FALSE;
1476 }
1477
1478 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1479 if (strcmp (pType->mTypeName, TypeName) == 0) {
1480 return TRUE;
1481 }
1482 }
1483
1484 return FALSE;
1485 }
1486
1487 VOID
1488 CVfrVarDataTypeDB::Dump (
1489 IN FILE *File
1490 )
1491 {
1492 SVfrDataType *pTNode;
1493 SVfrDataField *pFNode;
1494
1495 fprintf (File, "\n\n***************************************************************\n");
1496 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
1497 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1498 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1499 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
1500 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1501 if (pFNode->mArrayNum > 0) {
1502 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
1503 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
1504 } else {
1505 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
1506 pFNode->mFieldName, pFNode->mFieldType->mTypeName);
1507 }
1508 }
1509 fprintf (File, "\t\t};\n");
1510 fprintf (File, "---------------------------------------------------------------\n");
1511 }
1512 fprintf (File, "***************************************************************\n");
1513 }
1514
1515 #ifdef CVFR_VARDATATYPEDB_DEBUG
1516 VOID
1517 CVfrVarDataTypeDB::ParserDB (
1518 VOID
1519 )
1520 {
1521 SVfrDataType *pTNode;
1522 SVfrDataField *pFNode;
1523
1524 printf ("***************************************************************\n");
1525 printf ("\t\tmPackAlign = %x\n", mPackAlign);
1526 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1527 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1528 printf ("\t\tstruct %s {\n", pTNode->mTypeName);
1529 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1530 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
1531 }
1532 printf ("\t\t};\n");
1533 printf ("---------------------------------------------------------------\n");
1534 }
1535 printf ("***************************************************************\n");
1536 }
1537 #endif
1538
1539 SVfrVarStorageNode::SVfrVarStorageNode (
1540 IN EFI_GUID *Guid,
1541 IN CHAR8 *StoreName,
1542 IN EFI_VARSTORE_ID VarStoreId,
1543 IN EFI_STRING_ID VarName,
1544 IN UINT32 VarSize,
1545 IN BOOLEAN Flag
1546 )
1547 {
1548 if (Guid != NULL) {
1549 mGuid = *Guid;
1550 } else {
1551 memset (&mGuid, 0, sizeof (EFI_GUID));
1552 }
1553 if (StoreName != NULL) {
1554 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1555 strcpy (mVarStoreName, StoreName);
1556 } else {
1557 mVarStoreName = NULL;
1558 }
1559 mNext = NULL;
1560 mVarStoreId = VarStoreId;
1561 mVarStoreType = EFI_VFR_VARSTORE_EFI;
1562 mStorageInfo.mEfiVar.mEfiVarName = VarName;
1563 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
1564 mAssignedFlag = Flag;
1565 }
1566
1567 SVfrVarStorageNode::SVfrVarStorageNode (
1568 IN EFI_GUID *Guid,
1569 IN CHAR8 *StoreName,
1570 IN EFI_VARSTORE_ID VarStoreId,
1571 IN SVfrDataType *DataType,
1572 IN BOOLEAN BitsVarstore,
1573 IN BOOLEAN Flag
1574 )
1575 {
1576 if (Guid != NULL) {
1577 mGuid = *Guid;
1578 } else {
1579 memset (&mGuid, 0, sizeof (EFI_GUID));
1580 }
1581 if (StoreName != NULL) {
1582 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1583 strcpy (mVarStoreName, StoreName);
1584 } else {
1585 mVarStoreName = NULL;
1586 }
1587 mNext = NULL;
1588 mVarStoreId = VarStoreId;
1589 if (BitsVarstore) {
1590 mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;
1591 } else {
1592 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
1593 }
1594 mStorageInfo.mDataType = DataType;
1595 mAssignedFlag = Flag;
1596 }
1597
1598 SVfrVarStorageNode::SVfrVarStorageNode (
1599 IN CHAR8 *StoreName,
1600 IN EFI_VARSTORE_ID VarStoreId
1601 )
1602 {
1603 memset (&mGuid, 0, sizeof (EFI_GUID));
1604 if (StoreName != NULL) {
1605 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1606 strcpy (mVarStoreName, StoreName);
1607 } else {
1608 mVarStoreName = NULL;
1609 }
1610 mNext = NULL;
1611 mVarStoreId = VarStoreId;
1612 mVarStoreType = EFI_VFR_VARSTORE_NAME;
1613 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
1614 mStorageInfo.mNameSpace.mTableSize = 0;
1615 mAssignedFlag = FALSE;
1616 }
1617
1618 SVfrVarStorageNode::~SVfrVarStorageNode (
1619 VOID
1620 )
1621 {
1622 if (mVarStoreName != NULL) {
1623 delete[] mVarStoreName;
1624 }
1625
1626 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
1627 delete[] mStorageInfo.mNameSpace.mNameTable;
1628 }
1629 }
1630
1631 CVfrDataStorage::CVfrDataStorage (
1632 VOID
1633 )
1634 {
1635 UINT32 Index;
1636
1637 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1638 mFreeVarStoreIdBitMap[Index] = 0;
1639 }
1640
1641 // Question ID 0 is reserved.
1642 mFreeVarStoreIdBitMap[0] = 0x80000000;
1643
1644 mBufferVarStoreList = NULL;
1645 mEfiVarStoreList = NULL;
1646 mNameVarStoreList = NULL;
1647 mCurrVarStorageNode = NULL;
1648 mNewVarStorageNode = NULL;
1649 mBufferFieldInfoListHead = NULL;
1650 mBufferFieldInfoListTail = NULL;
1651 }
1652
1653 CVfrDataStorage::~CVfrDataStorage (
1654 VOID
1655 )
1656 {
1657 SVfrVarStorageNode *pNode;
1658
1659 while (mBufferVarStoreList != NULL) {
1660 pNode = mBufferVarStoreList;
1661 mBufferVarStoreList = mBufferVarStoreList->mNext;
1662 delete pNode;
1663 }
1664 while (mEfiVarStoreList != NULL) {
1665 pNode = mEfiVarStoreList;
1666 mEfiVarStoreList = mEfiVarStoreList->mNext;
1667 delete pNode;
1668 }
1669 while (mNameVarStoreList != NULL) {
1670 pNode = mNameVarStoreList;
1671 mNameVarStoreList = mNameVarStoreList->mNext;
1672 delete pNode;
1673 }
1674 if (mNewVarStorageNode != NULL) {
1675 delete mNewVarStorageNode;
1676 }
1677 }
1678
1679 EFI_VARSTORE_ID
1680 CVfrDataStorage::GetFreeVarStoreId (
1681 EFI_VFR_VARSTORE_TYPE VarType
1682 )
1683 {
1684 UINT32 Index, Mask, Offset;
1685
1686 //
1687 // Assign the different ID range for the different type VarStore to support Framework Vfr
1688 //
1689 Index = 0;
1690 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
1691 Index = 0;
1692 } else if (VarType == EFI_VFR_VARSTORE_EFI) {
1693 Index = 1;
1694 } else if (VarType == EFI_VFR_VARSTORE_NAME) {
1695 Index = 2;
1696 }
1697
1698 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1699 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1700 break;
1701 }
1702 }
1703
1704 if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
1705 return EFI_VARSTORE_ID_INVALID;
1706 }
1707
1708 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1709 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1710 mFreeVarStoreIdBitMap[Index] |= Mask;
1711 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1712 }
1713 }
1714
1715 return EFI_VARSTORE_ID_INVALID;
1716 }
1717
1718 BOOLEAN
1719 CVfrDataStorage::ChekVarStoreIdFree (
1720 IN EFI_VARSTORE_ID VarStoreId
1721 )
1722 {
1723 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1724 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1725
1726 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1727 }
1728
1729 VOID
1730 CVfrDataStorage::MarkVarStoreIdUsed (
1731 IN EFI_VARSTORE_ID VarStoreId
1732 )
1733 {
1734 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1735 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1736
1737 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1738 }
1739
1740 VOID
1741 CVfrDataStorage::MarkVarStoreIdUnused (
1742 IN EFI_VARSTORE_ID VarStoreId
1743 )
1744 {
1745 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1746 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1747
1748 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1749 }
1750
1751 EFI_VFR_RETURN_CODE
1752 CVfrDataStorage::DeclareNameVarStoreBegin (
1753 IN CHAR8 *StoreName,
1754 IN EFI_VARSTORE_ID VarStoreId
1755 )
1756 {
1757 SVfrVarStorageNode *pNode = NULL;
1758 EFI_VARSTORE_ID TmpVarStoreId;
1759
1760 if (StoreName == NULL) {
1761 return VFR_RETURN_FATAL_ERROR;
1762 }
1763
1764 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
1765 return VFR_RETURN_REDEFINED;
1766 }
1767
1768 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1769 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1770 } else {
1771 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1772 return VFR_RETURN_VARSTOREID_REDEFINED;
1773 }
1774 MarkVarStoreIdUsed (VarStoreId);
1775 }
1776
1777 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1778 return VFR_RETURN_UNDEFINED;
1779 }
1780
1781 mNewVarStorageNode = pNode;
1782
1783 return VFR_RETURN_SUCCESS;
1784 }
1785
1786 EFI_VFR_RETURN_CODE
1787 CVfrDataStorage::NameTableAddItem (
1788 IN EFI_STRING_ID Item
1789 )
1790 {
1791 EFI_VARSTORE_ID *NewTable, *OldTable;
1792 UINT32 TableSize;
1793
1794 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1795 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1796
1797 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1798 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1799 return VFR_RETURN_OUT_FOR_RESOURCES;
1800 }
1801 memcpy (NewTable, OldTable, TableSize);
1802 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1803 }
1804
1805 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1806 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1807
1808 return VFR_RETURN_SUCCESS;
1809 }
1810
1811 EFI_VFR_RETURN_CODE
1812 CVfrDataStorage::DeclareNameVarStoreEnd (
1813 IN EFI_GUID *Guid
1814 )
1815 {
1816 mNewVarStorageNode->mGuid = *Guid;
1817 mNewVarStorageNode->mNext = mNameVarStoreList;
1818 mNameVarStoreList = mNewVarStorageNode;
1819
1820 mNewVarStorageNode = NULL;
1821
1822 return VFR_RETURN_SUCCESS;
1823 }
1824
1825 EFI_VFR_RETURN_CODE
1826 CVfrDataStorage::DeclareEfiVarStore (
1827 IN CHAR8 *StoreName,
1828 IN EFI_GUID *Guid,
1829 IN EFI_STRING_ID NameStrId,
1830 IN UINT32 VarSize,
1831 IN BOOLEAN Flag
1832 )
1833 {
1834 SVfrVarStorageNode *pNode;
1835 EFI_VARSTORE_ID VarStoreId;
1836
1837 if ((StoreName == NULL) || (Guid == NULL)) {
1838 return VFR_RETURN_FATAL_ERROR;
1839 }
1840
1841 if (VarSize > sizeof (UINT64)) {
1842 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1843 }
1844
1845 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1846 return VFR_RETURN_REDEFINED;
1847 }
1848
1849 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
1850 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
1851 return VFR_RETURN_OUT_FOR_RESOURCES;
1852 }
1853
1854 pNode->mNext = mEfiVarStoreList;
1855 mEfiVarStoreList = pNode;
1856
1857 return VFR_RETURN_SUCCESS;
1858 }
1859
1860 EFI_VFR_RETURN_CODE
1861 CVfrDataStorage::DeclareBufferVarStore (
1862 IN CHAR8 *StoreName,
1863 IN EFI_GUID *Guid,
1864 IN CVfrVarDataTypeDB *DataTypeDB,
1865 IN CHAR8 *TypeName,
1866 IN EFI_VARSTORE_ID VarStoreId,
1867 IN BOOLEAN IsBitVarStore,
1868 IN BOOLEAN Flag
1869 )
1870 {
1871 SVfrVarStorageNode *pNew = NULL;
1872 SVfrDataType *pDataType = NULL;
1873 EFI_VARSTORE_ID TempVarStoreId;
1874
1875 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1876 return VFR_RETURN_FATAL_ERROR;
1877 }
1878
1879 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1880 return VFR_RETURN_REDEFINED;
1881 }
1882
1883 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1884
1885 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1886 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1887 } else {
1888 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1889 return VFR_RETURN_VARSTOREID_REDEFINED;
1890 }
1891 MarkVarStoreIdUsed (VarStoreId);
1892 }
1893
1894 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {
1895 return VFR_RETURN_OUT_FOR_RESOURCES;
1896 }
1897
1898 pNew->mNext = mBufferVarStoreList;
1899 mBufferVarStoreList = pNew;
1900
1901 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
1902 return VFR_RETURN_FATAL_ERROR;
1903 }
1904
1905 return VFR_RETURN_SUCCESS;
1906 }
1907
1908 EFI_VFR_RETURN_CODE
1909 CVfrDataStorage::GetVarStoreByDataType (
1910 IN CHAR8 *DataTypeName,
1911 OUT SVfrVarStorageNode **VarNode,
1912 IN EFI_GUID *VarGuid
1913 )
1914 {
1915 SVfrVarStorageNode *pNode;
1916 SVfrVarStorageNode *MatchNode;
1917
1918 //
1919 // Framework VFR uses Data type name as varstore name, so don't need check again.
1920 //
1921 if (VfrCompatibleMode) {
1922 return VFR_RETURN_UNDEFINED;
1923 }
1924
1925 MatchNode = NULL;
1926 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1927 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
1928 continue;
1929 }
1930
1931 if ((VarGuid != NULL)) {
1932 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1933 *VarNode = pNode;
1934 return VFR_RETURN_SUCCESS;
1935 }
1936 } else {
1937 if (MatchNode == NULL) {
1938 MatchNode = pNode;
1939 } else {
1940 //
1941 // More than one varstores referred the same data structures.
1942 //
1943 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
1944 }
1945 }
1946 }
1947
1948 if (MatchNode == NULL) {
1949 return VFR_RETURN_UNDEFINED;
1950 }
1951
1952 *VarNode = MatchNode;
1953 return VFR_RETURN_SUCCESS;
1954 }
1955
1956 EFI_VARSTORE_ID
1957 CVfrDataStorage::CheckGuidField (
1958 IN SVfrVarStorageNode *pNode,
1959 IN EFI_GUID *StoreGuid,
1960 IN BOOLEAN *HasFoundOne,
1961 OUT EFI_VFR_RETURN_CODE *ReturnCode
1962 )
1963 {
1964 if (StoreGuid != NULL) {
1965 //
1966 // If has guid info, compare the guid filed.
1967 //
1968 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1969 //
1970 // Both name and guid are same, this this varstore.
1971 //
1972 mCurrVarStorageNode = pNode;
1973 *ReturnCode = VFR_RETURN_SUCCESS;
1974 return TRUE;
1975 }
1976 } else {
1977 //
1978 // Not has Guid field, check whether this name is the only one.
1979 //
1980 if (*HasFoundOne) {
1981 //
1982 // The name has conflict, return name redefined.
1983 //
1984 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
1985 return TRUE;
1986 }
1987
1988 *HasFoundOne = TRUE;
1989 mCurrVarStorageNode = pNode;
1990 }
1991
1992 return FALSE;
1993 }
1994
1995 /**
1996 Base on the input store name and guid to find the varstore id.
1997
1998 If both name and guid are inputed, base on the name and guid to
1999 found the varstore. If only name inputed, base on the name to
2000 found the varstore and go on to check whether more than one varstore
2001 has the same name. If only has found one varstore, return this
2002 varstore; if more than one varstore has same name, return varstore
2003 name redefined error. If no varstore found by varstore name, call
2004 function GetVarStoreByDataType and use inputed varstore name as
2005 data type name to search.
2006 **/
2007 EFI_VFR_RETURN_CODE
2008 CVfrDataStorage::GetVarStoreId (
2009 IN CHAR8 *StoreName,
2010 OUT EFI_VARSTORE_ID *VarStoreId,
2011 IN EFI_GUID *StoreGuid
2012 )
2013 {
2014 EFI_VFR_RETURN_CODE ReturnCode;
2015 SVfrVarStorageNode *pNode;
2016 BOOLEAN HasFoundOne = FALSE;
2017
2018 mCurrVarStorageNode = NULL;
2019
2020 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2021 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
2022 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
2023 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2024 return ReturnCode;
2025 }
2026 }
2027 }
2028
2029 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2030 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
2031 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
2032 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2033 return ReturnCode;
2034 }
2035 }
2036 }
2037
2038 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2039 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
2040 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
2041 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2042 return ReturnCode;
2043 }
2044 }
2045 }
2046
2047 if (HasFoundOne) {
2048 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2049 return VFR_RETURN_SUCCESS;
2050 }
2051
2052 *VarStoreId = EFI_VARSTORE_ID_INVALID;
2053
2054 //
2055 // Assume that Data structure name is used as StoreName, and check again.
2056 //
2057 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
2058 if (pNode != NULL) {
2059 mCurrVarStorageNode = pNode;
2060 *VarStoreId = pNode->mVarStoreId;
2061 }
2062
2063 return ReturnCode;
2064 }
2065
2066 EFI_VFR_RETURN_CODE
2067 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2068 IN EFI_VARSTORE_ID VarStoreId,
2069 OUT CHAR8 **DataTypeName
2070 )
2071 {
2072 SVfrVarStorageNode *pNode;
2073
2074 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2075 return VFR_RETURN_FATAL_ERROR;
2076 }
2077
2078 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2079 if (pNode->mVarStoreId == VarStoreId) {
2080 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
2081 return VFR_RETURN_SUCCESS;
2082 }
2083 }
2084
2085 return VFR_RETURN_UNDEFINED;
2086 }
2087
2088 EFI_VFR_VARSTORE_TYPE
2089 CVfrDataStorage::GetVarStoreType (
2090 IN EFI_VARSTORE_ID VarStoreId
2091 )
2092 {
2093 SVfrVarStorageNode *pNode;
2094 EFI_VFR_VARSTORE_TYPE VarStoreType;
2095
2096 VarStoreType = EFI_VFR_VARSTORE_INVALID;
2097
2098 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2099 return VarStoreType;
2100 }
2101
2102 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2103 if (pNode->mVarStoreId == VarStoreId) {
2104 VarStoreType = pNode->mVarStoreType;
2105 return VarStoreType;
2106 }
2107 }
2108
2109 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2110 if (pNode->mVarStoreId == VarStoreId) {
2111 VarStoreType = pNode->mVarStoreType;
2112 return VarStoreType;
2113 }
2114 }
2115
2116 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2117 if (pNode->mVarStoreId == VarStoreId) {
2118 VarStoreType = pNode->mVarStoreType;
2119 return VarStoreType;
2120 }
2121 }
2122
2123 return VarStoreType;
2124 }
2125
2126 EFI_GUID *
2127 CVfrDataStorage::GetVarStoreGuid (
2128 IN EFI_VARSTORE_ID VarStoreId
2129 )
2130 {
2131 SVfrVarStorageNode *pNode;
2132 EFI_GUID *VarGuid;
2133
2134 VarGuid = NULL;
2135
2136 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2137 return VarGuid;
2138 }
2139
2140 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2141 if (pNode->mVarStoreId == VarStoreId) {
2142 VarGuid = &pNode->mGuid;
2143 return VarGuid;
2144 }
2145 }
2146
2147 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2148 if (pNode->mVarStoreId == VarStoreId) {
2149 VarGuid = &pNode->mGuid;
2150 return VarGuid;
2151 }
2152 }
2153
2154 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2155 if (pNode->mVarStoreId == VarStoreId) {
2156 VarGuid = &pNode->mGuid;
2157 return VarGuid;
2158 }
2159 }
2160
2161 return VarGuid;
2162 }
2163
2164 EFI_VFR_RETURN_CODE
2165 CVfrDataStorage::GetVarStoreName (
2166 IN EFI_VARSTORE_ID VarStoreId,
2167 OUT CHAR8 **VarStoreName
2168 )
2169 {
2170 SVfrVarStorageNode *pNode;
2171
2172 if (VarStoreName == NULL) {
2173 return VFR_RETURN_FATAL_ERROR;
2174 }
2175
2176 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2177 if (pNode->mVarStoreId == VarStoreId) {
2178 *VarStoreName = pNode->mVarStoreName;
2179 return VFR_RETURN_SUCCESS;
2180 }
2181 }
2182
2183 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2184 if (pNode->mVarStoreId == VarStoreId) {
2185 *VarStoreName = pNode->mVarStoreName;
2186 return VFR_RETURN_SUCCESS;
2187 }
2188 }
2189
2190 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2191 if (pNode->mVarStoreId == VarStoreId) {
2192 *VarStoreName = pNode->mVarStoreName;
2193 return VFR_RETURN_SUCCESS;
2194 }
2195 }
2196
2197 *VarStoreName = NULL;
2198 return VFR_RETURN_UNDEFINED;
2199 }
2200
2201 EFI_VFR_RETURN_CODE
2202 CVfrDataStorage::GetEfiVarStoreInfo (
2203 IN OUT EFI_VARSTORE_INFO *Info
2204 )
2205 {
2206 if (Info == NULL) {
2207 return VFR_RETURN_FATAL_ERROR;
2208 }
2209
2210 if (mCurrVarStorageNode == NULL) {
2211 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
2212 }
2213
2214 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
2215 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
2216 switch (Info->mVarTotalSize) {
2217 case 1:
2218 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
2219 break;
2220 case 2:
2221 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
2222 break;
2223 case 4:
2224 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
2225 break;
2226 case 8:
2227 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
2228 break;
2229 default :
2230 return VFR_RETURN_FATAL_ERROR;
2231 }
2232
2233 return VFR_RETURN_SUCCESS;
2234 }
2235
2236 EFI_VFR_RETURN_CODE
2237 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2238 IN EFI_VARSTORE_INFO *Info
2239 )
2240 {
2241 BufferVarStoreFieldInfoNode *pNew;
2242
2243 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
2244 return VFR_RETURN_FATAL_ERROR;
2245 }
2246
2247 if (mBufferFieldInfoListHead == NULL) {
2248 mBufferFieldInfoListHead = pNew;
2249 mBufferFieldInfoListTail= pNew;
2250 } else {
2251 mBufferFieldInfoListTail->mNext = pNew;
2252 mBufferFieldInfoListTail = pNew;
2253 }
2254
2255 return VFR_RETURN_SUCCESS;
2256 }
2257
2258 EFI_VFR_RETURN_CODE
2259 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2260 IN OUT EFI_VARSTORE_INFO *Info
2261 )
2262 {
2263 BufferVarStoreFieldInfoNode *pNode;
2264
2265 pNode = mBufferFieldInfoListHead;
2266 while (pNode != NULL) {
2267 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
2268 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
2269 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
2270 Info->mVarType = pNode->mVarStoreInfo.mVarType;
2271 return VFR_RETURN_SUCCESS;
2272 }
2273 pNode = pNode->mNext;
2274 }
2275 return VFR_RETURN_FATAL_ERROR;
2276 }
2277
2278 EFI_VFR_RETURN_CODE
2279 CVfrDataStorage::GetNameVarStoreInfo (
2280 OUT EFI_VARSTORE_INFO *Info,
2281 IN UINT32 Index
2282 )
2283 {
2284 if (Info == NULL) {
2285 return VFR_RETURN_FATAL_ERROR;
2286 }
2287
2288 if (mCurrVarStorageNode == NULL) {
2289 return VFR_RETURN_GET_NVVARSTORE_ERROR;
2290 }
2291
2292 //
2293 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2294 //
2295 if (VfrCompatibleMode) {
2296 if (Index == 0) {
2297 return VFR_RETURN_ERROR_ARRARY_NUM;
2298 }
2299 Index --;
2300 }
2301
2302 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
2303
2304 return VFR_RETURN_SUCCESS;
2305 }
2306
2307 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2308 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
2309 IN CHAR8 *RefName,
2310 IN EFI_STRING_ID DefaultStoreNameId,
2311 IN UINT16 DefaultId
2312 )
2313 {
2314 mObjBinAddr = ObjBinAddr;
2315
2316 if (RefName != NULL) {
2317 mRefName = new CHAR8[strlen (RefName) + 1];
2318 strcpy (mRefName, RefName);
2319 } else {
2320 mRefName = NULL;
2321 }
2322
2323 mNext = NULL;
2324 mDefaultId = DefaultId;
2325 mDefaultStoreNameId = DefaultStoreNameId;
2326 }
2327
2328 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2329 VOID
2330 )
2331 {
2332 if (mRefName != NULL) {
2333 delete[] mRefName;
2334 }
2335 }
2336
2337 CVfrDefaultStore::CVfrDefaultStore (
2338 VOID
2339 )
2340 {
2341 mDefaultStoreList = NULL;
2342 }
2343
2344 CVfrDefaultStore::~CVfrDefaultStore (
2345 VOID
2346 )
2347 {
2348 SVfrDefaultStoreNode *pTmp = NULL;
2349
2350 while (mDefaultStoreList != NULL) {
2351 pTmp = mDefaultStoreList;
2352 mDefaultStoreList = mDefaultStoreList->mNext;
2353 delete pTmp;
2354 }
2355 }
2356
2357 EFI_VFR_RETURN_CODE
2358 CVfrDefaultStore::RegisterDefaultStore (
2359 IN CHAR8 *ObjBinAddr,
2360 IN CHAR8 *RefName,
2361 IN EFI_STRING_ID DefaultStoreNameId,
2362 IN UINT16 DefaultId
2363 )
2364 {
2365 SVfrDefaultStoreNode *pNode = NULL;
2366
2367 if (RefName == NULL) {
2368 return VFR_RETURN_FATAL_ERROR;
2369 }
2370
2371 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2372 if (strcmp (pNode->mRefName, RefName) == 0) {
2373 return VFR_RETURN_REDEFINED;
2374 }
2375 }
2376
2377 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
2378 return VFR_RETURN_OUT_FOR_RESOURCES;
2379 }
2380
2381 pNode->mNext = mDefaultStoreList;
2382 mDefaultStoreList = pNode;
2383
2384 return VFR_RETURN_SUCCESS;
2385 }
2386
2387 /*
2388 * assign new reference name or new default store name id only if
2389 * the original is invalid
2390 */
2391 EFI_VFR_RETURN_CODE
2392 CVfrDefaultStore::ReRegisterDefaultStoreById (
2393 IN UINT16 DefaultId,
2394 IN CHAR8 *RefName,
2395 IN EFI_STRING_ID DefaultStoreNameId
2396 )
2397 {
2398 SVfrDefaultStoreNode *pNode = NULL;
2399
2400 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2401 if (pNode->mDefaultId == DefaultId) {
2402 break;
2403 }
2404 }
2405
2406 if (pNode == NULL) {
2407 return VFR_RETURN_UNDEFINED;
2408 } else {
2409 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
2410 pNode->mDefaultStoreNameId = DefaultStoreNameId;
2411 if (pNode->mObjBinAddr != NULL) {
2412 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
2413 }
2414 } else {
2415 return VFR_RETURN_REDEFINED;
2416 }
2417
2418 if (RefName != NULL) {
2419 delete pNode->mRefName;
2420 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
2421 if (pNode->mRefName != NULL) {
2422 strcpy (pNode->mRefName, RefName);
2423 }
2424 }
2425 }
2426
2427 return VFR_RETURN_SUCCESS;
2428 }
2429
2430 BOOLEAN
2431 CVfrDefaultStore::DefaultIdRegistered (
2432 IN UINT16 DefaultId
2433 )
2434 {
2435 SVfrDefaultStoreNode *pNode = NULL;
2436
2437 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2438 if (pNode->mDefaultId == DefaultId) {
2439 return TRUE;
2440 }
2441 }
2442
2443 return FALSE;
2444 }
2445
2446 EFI_VFR_RETURN_CODE
2447 CVfrDefaultStore::GetDefaultId (
2448 IN CHAR8 *RefName,
2449 OUT UINT16 *DefaultId
2450 )
2451 {
2452 SVfrDefaultStoreNode *pTmp = NULL;
2453
2454 if (DefaultId == NULL) {
2455 return VFR_RETURN_FATAL_ERROR;
2456 }
2457
2458 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2459 if (strcmp (pTmp->mRefName, RefName) == 0) {
2460 *DefaultId = pTmp->mDefaultId;
2461 return VFR_RETURN_SUCCESS;
2462 }
2463 }
2464
2465 return VFR_RETURN_UNDEFINED;
2466 }
2467
2468 EFI_VFR_RETURN_CODE
2469 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2470 IN EFI_VARSTORE_ID DefaultId,
2471 IN EFI_VARSTORE_INFO &Info,
2472 IN CHAR8 *VarStoreName,
2473 IN EFI_GUID *VarStoreGuid,
2474 IN UINT8 Type,
2475 IN EFI_IFR_TYPE_VALUE Value
2476 )
2477 {
2478 SVfrDefaultStoreNode *pNode = NULL;
2479 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2480 INTN Returnvalue = 0;
2481
2482 if (VarStoreName == NULL) {
2483 return VFR_RETURN_FATAL_ERROR;
2484 }
2485
2486 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2487 if (pNode->mDefaultId == DefaultId) {
2488 break;
2489 }
2490 }
2491
2492 if (pNode == NULL) {
2493 return VFR_RETURN_UNDEFINED;
2494 }
2495
2496 gCVfrBufferConfig.Open ();
2497
2498 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2499 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
2500 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2501 goto WriteError;
2502 }
2503 }
2504
2505 gCVfrBufferConfig.Close ();
2506
2507 return VFR_RETURN_SUCCESS;
2508
2509 WriteError:
2510 gCVfrBufferConfig.Close ();
2511 return (EFI_VFR_RETURN_CODE)Returnvalue;
2512 }
2513
2514 SVfrRuleNode::SVfrRuleNode (
2515 IN CHAR8 *RuleName,
2516 IN UINT8 RuleId
2517 )
2518 {
2519 if (RuleName != NULL) {
2520 mRuleName = new CHAR8[strlen (RuleName) + 1];
2521 strcpy (mRuleName, RuleName);
2522 } else {
2523 mRuleName = NULL;
2524 }
2525
2526 mNext = NULL;
2527 mRuleId = RuleId;
2528 }
2529
2530 SVfrRuleNode::~SVfrRuleNode (
2531 VOID
2532 )
2533 {
2534 if (mRuleName != NULL) {
2535 delete[] mRuleName;
2536 }
2537 }
2538
2539 CVfrRulesDB::CVfrRulesDB ()
2540 {
2541 mRuleList = NULL;
2542 mFreeRuleId = EFI_VARSTORE_ID_START;
2543 }
2544
2545 CVfrRulesDB::~CVfrRulesDB ()
2546 {
2547 SVfrRuleNode *pNode;
2548
2549 while(mRuleList != NULL) {
2550 pNode = mRuleList;
2551 mRuleList = mRuleList->mNext;
2552 delete pNode;
2553 }
2554 }
2555
2556 VOID
2557 CVfrRulesDB::RegisterRule (
2558 IN CHAR8 *RuleName
2559 )
2560 {
2561 SVfrRuleNode *pNew;
2562
2563 if (RuleName == NULL) {
2564 return ;
2565 }
2566
2567 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2568 return ;
2569 }
2570
2571 mFreeRuleId++;
2572
2573 pNew->mNext = mRuleList;
2574 mRuleList = pNew;
2575 }
2576
2577 UINT8
2578 CVfrRulesDB::GetRuleId (
2579 IN CHAR8 *RuleName
2580 )
2581 {
2582 SVfrRuleNode *pNode;
2583
2584 if (RuleName == NULL) {
2585 return EFI_RULE_ID_INVALID;
2586 }
2587
2588 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2589 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2590 return pNode->mRuleId;
2591 }
2592 }
2593
2594 return EFI_RULE_ID_INVALID;
2595 }
2596
2597 CVfrRulesDB gCVfrRulesDB;
2598
2599 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2600 VOID
2601 )
2602 {
2603 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2604 mInfo.mVarName = EFI_STRING_ID_INVALID;
2605 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2606 mVarType = EFI_IFR_TYPE_OTHER;
2607 mVarTotalSize = 0;
2608 mIsBitVar = FALSE;
2609 }
2610
2611 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2612 IN EFI_VARSTORE_INFO &Info
2613 )
2614 {
2615 mVarStoreId = Info.mVarStoreId;
2616 mInfo.mVarName = Info.mInfo.mVarName;
2617 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2618 mVarType = Info.mVarType;
2619 mVarTotalSize = Info.mVarTotalSize;
2620 mIsBitVar = Info.mIsBitVar;
2621 }
2622
2623 EFI_VARSTORE_INFO&
2624 EFI_VARSTORE_INFO::operator= (
2625 IN CONST EFI_VARSTORE_INFO &Info
2626 )
2627 {
2628 if (this != &Info) {
2629 mVarStoreId = Info.mVarStoreId;
2630 mInfo.mVarName = Info.mInfo.mVarName;
2631 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2632 mVarType = Info.mVarType;
2633 mVarTotalSize = Info.mVarTotalSize;
2634 mIsBitVar = Info.mIsBitVar;
2635 }
2636
2637 return *this;
2638 }
2639
2640 BOOLEAN
2641 EFI_VARSTORE_INFO::operator == (
2642 IN EFI_VARSTORE_INFO *Info
2643 )
2644 {
2645 if ((mVarStoreId == Info->mVarStoreId) &&
2646 (mInfo.mVarName == Info->mInfo.mVarName) &&
2647 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2648 (mVarType == Info->mVarType) &&
2649 (mVarTotalSize == Info->mVarTotalSize) &&
2650 (mIsBitVar == Info->mIsBitVar)) {
2651 return TRUE;
2652 }
2653
2654 return FALSE;
2655 }
2656
2657 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2658 IN EFI_VARSTORE_INFO *Info
2659 )
2660 {
2661 mVarStoreInfo.mVarType = Info->mVarType;
2662 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
2663 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
2664 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
2665 mNext = NULL;
2666 }
2667
2668 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2669 {
2670 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
2671 mVarStoreInfo.mVarTotalSize = 0;
2672 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2673 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
2674 mNext = NULL;
2675 }
2676
2677 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2678
2679 EFI_QUESTION_ID
2680 CVfrQuestionDB::GetFreeQuestionId (
2681 VOID
2682 )
2683 {
2684 UINT32 Index, Mask, Offset;
2685
2686 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2687 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2688 break;
2689 }
2690 }
2691
2692 if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
2693 return EFI_QUESTION_ID_INVALID;
2694 }
2695
2696 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2697 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2698 mFreeQIdBitMap[Index] |= Mask;
2699 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2700 }
2701 }
2702
2703 return EFI_QUESTION_ID_INVALID;
2704 }
2705
2706 BOOLEAN
2707 CVfrQuestionDB::ChekQuestionIdFree (
2708 IN EFI_QUESTION_ID QId
2709 )
2710 {
2711 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2712 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2713
2714 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2715 }
2716
2717 VOID
2718 CVfrQuestionDB::MarkQuestionIdUsed (
2719 IN EFI_QUESTION_ID QId
2720 )
2721 {
2722 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2723 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2724
2725 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2726 }
2727
2728 VOID
2729 CVfrQuestionDB::MarkQuestionIdUnused (
2730 IN EFI_QUESTION_ID QId
2731 )
2732 {
2733 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2734 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2735
2736 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2737 }
2738
2739 SVfrQuestionNode::SVfrQuestionNode (
2740 IN CHAR8 *Name,
2741 IN CHAR8 *VarIdStr,
2742 IN UINT32 BitMask
2743 )
2744 {
2745 mName = NULL;
2746 mVarIdStr = NULL;
2747 mQuestionId = EFI_QUESTION_ID_INVALID;
2748 mBitMask = BitMask;
2749 mNext = NULL;
2750 mQtype = QUESTION_NORMAL;
2751
2752 if (Name == NULL) {
2753 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2754 strcpy (mName, "$DEFAULT");
2755 } else {
2756 mName = new CHAR8[strlen (Name) + 1];
2757 strcpy (mName, Name);
2758 }
2759
2760 if (VarIdStr != NULL) {
2761 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2762 strcpy (mVarIdStr, VarIdStr);
2763 } else {
2764 mVarIdStr = new CHAR8[strlen ("$") + 1];
2765 strcpy (mVarIdStr, "$");
2766 }
2767 }
2768
2769 SVfrQuestionNode::~SVfrQuestionNode (
2770 VOID
2771 )
2772 {
2773 if (mName != NULL) {
2774 delete[] mName;
2775 }
2776
2777 if (mVarIdStr != NULL) {
2778 delete[] mVarIdStr;
2779 }
2780 }
2781
2782 CVfrQuestionDB::CVfrQuestionDB ()
2783 {
2784 UINT32 Index;
2785
2786 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2787 mFreeQIdBitMap[Index] = 0;
2788 }
2789
2790 // Question ID 0 is reserved.
2791 mFreeQIdBitMap[0] = 0x80000000;
2792 mQuestionList = NULL;
2793 }
2794
2795 CVfrQuestionDB::~CVfrQuestionDB ()
2796 {
2797 SVfrQuestionNode *pNode;
2798
2799 while (mQuestionList != NULL) {
2800 pNode = mQuestionList;
2801 mQuestionList = mQuestionList->mNext;
2802 delete pNode;
2803 }
2804 }
2805
2806 //
2807 // Reset to init state
2808 //
2809 VOID
2810 CVfrQuestionDB::ResetInit(
2811 IN VOID
2812 )
2813 {
2814 UINT32 Index;
2815 SVfrQuestionNode *pNode;
2816
2817 while (mQuestionList != NULL) {
2818 pNode = mQuestionList;
2819 mQuestionList = mQuestionList->mNext;
2820 delete pNode;
2821 }
2822
2823 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2824 mFreeQIdBitMap[Index] = 0;
2825 }
2826
2827 // Question ID 0 is reserved.
2828 mFreeQIdBitMap[0] = 0x80000000;
2829 mQuestionList = NULL;
2830 }
2831
2832 VOID
2833 CVfrQuestionDB::PrintAllQuestion (
2834 VOID
2835 )
2836 {
2837 SVfrQuestionNode *pNode = NULL;
2838
2839 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2840 printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2841 }
2842 }
2843
2844 EFI_VFR_RETURN_CODE
2845 CVfrQuestionDB::RegisterQuestion (
2846 IN CHAR8 *Name,
2847 IN CHAR8 *VarIdStr,
2848 IN OUT EFI_QUESTION_ID &QuestionId
2849 )
2850 {
2851 SVfrQuestionNode *pNode = NULL;
2852
2853 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2854 return VFR_RETURN_REDEFINED;
2855 }
2856
2857 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2858 return VFR_RETURN_OUT_FOR_RESOURCES;
2859 }
2860
2861 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2862 QuestionId = GetFreeQuestionId ();
2863 } else {
2864 //
2865 // For Framework Vfr, don't check question ID conflict.
2866 //
2867 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
2868 delete pNode;
2869 return VFR_RETURN_QUESTIONID_REDEFINED;
2870 }
2871 MarkQuestionIdUsed (QuestionId);
2872 }
2873 pNode->mQuestionId = QuestionId;
2874
2875 pNode->mNext = mQuestionList;
2876 mQuestionList = pNode;
2877
2878 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2879
2880 return VFR_RETURN_SUCCESS;
2881 }
2882
2883 VOID
2884 CVfrQuestionDB::RegisterOldDateQuestion (
2885 IN CHAR8 *YearVarId,
2886 IN CHAR8 *MonthVarId,
2887 IN CHAR8 *DayVarId,
2888 IN OUT EFI_QUESTION_ID &QuestionId
2889 )
2890 {
2891 SVfrQuestionNode *pNode[3] = {NULL, };
2892 UINT32 Index;
2893
2894 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2895 return;
2896 }
2897
2898 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2899 goto Err;
2900 }
2901 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2902 goto Err;
2903 }
2904 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2905 goto Err;
2906 }
2907
2908 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2909 QuestionId = GetFreeQuestionId ();
2910 } else {
2911 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2912 goto Err;
2913 }
2914 MarkQuestionIdUsed (QuestionId);
2915 }
2916
2917 pNode[0]->mQuestionId = QuestionId;
2918 pNode[1]->mQuestionId = QuestionId;
2919 pNode[2]->mQuestionId = QuestionId;
2920 pNode[0]->mQtype = QUESTION_DATE;
2921 pNode[1]->mQtype = QUESTION_DATE;
2922 pNode[2]->mQtype = QUESTION_DATE;
2923 pNode[0]->mNext = pNode[1];
2924 pNode[1]->mNext = pNode[2];
2925 pNode[2]->mNext = mQuestionList;
2926 mQuestionList = pNode[0];
2927
2928 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2929 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2930 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2931
2932 return;
2933
2934 Err:
2935 for (Index = 0; Index < 3; Index++) {
2936 if (pNode[Index] != NULL) {
2937 delete pNode[Index];
2938 }
2939 }
2940 QuestionId = EFI_QUESTION_ID_INVALID;
2941 }
2942
2943 VOID
2944 CVfrQuestionDB::RegisterNewDateQuestion (
2945 IN CHAR8 *Name,
2946 IN CHAR8 *BaseVarId,
2947 IN OUT EFI_QUESTION_ID &QuestionId
2948 )
2949 {
2950 SVfrQuestionNode *pNode[3] = {NULL, };
2951 UINT32 Len;
2952 CHAR8 *VarIdStr[3] = {NULL, };
2953 CHAR8 Index;
2954
2955 if (BaseVarId == NULL && Name == NULL) {
2956 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2957 QuestionId = GetFreeQuestionId ();
2958 } else {
2959 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2960 goto Err;
2961 }
2962 MarkQuestionIdUsed (QuestionId);
2963 }
2964 return;
2965 }
2966
2967 if (BaseVarId != NULL) {
2968 Len = strlen (BaseVarId);
2969
2970 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2971 if (VarIdStr[0] != NULL) {
2972 strcpy (VarIdStr[0], BaseVarId);
2973 strcat (VarIdStr[0], ".Year");
2974 }
2975 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2976 if (VarIdStr[1] != NULL) {
2977 strcpy (VarIdStr[1], BaseVarId);
2978 strcat (VarIdStr[1], ".Month");
2979 }
2980 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2981 if (VarIdStr[2] != NULL) {
2982 strcpy (VarIdStr[2], BaseVarId);
2983 strcat (VarIdStr[2], ".Day");
2984 }
2985 } else {
2986 Len = strlen (Name);
2987
2988 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2989 if (VarIdStr[0] != NULL) {
2990 strcpy (VarIdStr[0], Name);
2991 strcat (VarIdStr[0], ".Year");
2992 }
2993 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2994 if (VarIdStr[1] != NULL) {
2995 strcpy (VarIdStr[1], Name);
2996 strcat (VarIdStr[1], ".Month");
2997 }
2998 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2999 if (VarIdStr[2] != NULL) {
3000 strcpy (VarIdStr[2], Name);
3001 strcat (VarIdStr[2], ".Day");
3002 }
3003 }
3004
3005 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
3006 goto Err;
3007 }
3008 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
3009 goto Err;
3010 }
3011 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
3012 goto Err;
3013 }
3014
3015 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3016 QuestionId = GetFreeQuestionId ();
3017 } else {
3018 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3019 goto Err;
3020 }
3021 MarkQuestionIdUsed (QuestionId);
3022 }
3023
3024 pNode[0]->mQuestionId = QuestionId;
3025 pNode[1]->mQuestionId = QuestionId;
3026 pNode[2]->mQuestionId = QuestionId;
3027 pNode[0]->mQtype = QUESTION_DATE;
3028 pNode[1]->mQtype = QUESTION_DATE;
3029 pNode[2]->mQtype = QUESTION_DATE;
3030 pNode[0]->mNext = pNode[1];
3031 pNode[1]->mNext = pNode[2];
3032 pNode[2]->mNext = mQuestionList;
3033 mQuestionList = pNode[0];
3034
3035 for (Index = 0; Index < 3; Index++) {
3036 if (VarIdStr[Index] != NULL) {
3037 delete[] VarIdStr[Index];
3038 VarIdStr[Index] = NULL;
3039 }
3040 }
3041
3042 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3043 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3044 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3045
3046 return;
3047
3048 Err:
3049 for (Index = 0; Index < 3; Index++) {
3050 if (pNode[Index] != NULL) {
3051 delete pNode[Index];
3052 }
3053
3054 if (VarIdStr[Index] != NULL) {
3055 delete[] VarIdStr [Index];
3056 VarIdStr [Index] = NULL;
3057 }
3058 }
3059 }
3060
3061 VOID
3062 CVfrQuestionDB::RegisterOldTimeQuestion (
3063 IN CHAR8 *HourVarId,
3064 IN CHAR8 *MinuteVarId,
3065 IN CHAR8 *SecondVarId,
3066 IN OUT EFI_QUESTION_ID &QuestionId
3067 )
3068 {
3069 SVfrQuestionNode *pNode[3] = {NULL, };
3070 UINT32 Index;
3071
3072 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
3073 return;
3074 }
3075
3076 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
3077 goto Err;
3078 }
3079 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
3080 goto Err;
3081 }
3082 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
3083 goto Err;
3084 }
3085
3086 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3087 QuestionId = GetFreeQuestionId ();
3088 } else {
3089 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3090 goto Err;
3091 }
3092 MarkQuestionIdUsed (QuestionId);
3093 }
3094
3095 pNode[0]->mQuestionId = QuestionId;
3096 pNode[1]->mQuestionId = QuestionId;
3097 pNode[2]->mQuestionId = QuestionId;
3098 pNode[0]->mQtype = QUESTION_TIME;
3099 pNode[1]->mQtype = QUESTION_TIME;
3100 pNode[2]->mQtype = QUESTION_TIME;
3101 pNode[0]->mNext = pNode[1];
3102 pNode[1]->mNext = pNode[2];
3103 pNode[2]->mNext = mQuestionList;
3104 mQuestionList = pNode[0];
3105
3106 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3107 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3108 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3109
3110 return;
3111
3112 Err:
3113 for (Index = 0; Index < 3; Index++) {
3114 if (pNode[Index] != NULL) {
3115 delete pNode[Index];
3116 }
3117 }
3118 QuestionId = EFI_QUESTION_ID_INVALID;
3119 }
3120
3121 VOID
3122 CVfrQuestionDB::RegisterNewTimeQuestion (
3123 IN CHAR8 *Name,
3124 IN CHAR8 *BaseVarId,
3125 IN OUT EFI_QUESTION_ID &QuestionId
3126 )
3127 {
3128 SVfrQuestionNode *pNode[3] = {NULL, };
3129 UINT32 Len;
3130 CHAR8 *VarIdStr[3] = {NULL, };
3131 CHAR8 Index;
3132
3133 if (BaseVarId == NULL && Name == NULL) {
3134 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3135 QuestionId = GetFreeQuestionId ();
3136 } else {
3137 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3138 goto Err;
3139 }
3140 MarkQuestionIdUsed (QuestionId);
3141 }
3142 return;
3143 }
3144
3145 if (BaseVarId != NULL) {
3146 Len = strlen (BaseVarId);
3147
3148 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
3149 if (VarIdStr[0] != NULL) {
3150 strcpy (VarIdStr[0], BaseVarId);
3151 strcat (VarIdStr[0], ".Hour");
3152 }
3153 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
3154 if (VarIdStr[1] != NULL) {
3155 strcpy (VarIdStr[1], BaseVarId);
3156 strcat (VarIdStr[1], ".Minute");
3157 }
3158 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
3159 if (VarIdStr[2] != NULL) {
3160 strcpy (VarIdStr[2], BaseVarId);
3161 strcat (VarIdStr[2], ".Second");
3162 }
3163 } else {
3164 Len = strlen (Name);
3165
3166 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
3167 if (VarIdStr[0] != NULL) {
3168 strcpy (VarIdStr[0], Name);
3169 strcat (VarIdStr[0], ".Hour");
3170 }
3171 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
3172 if (VarIdStr[1] != NULL) {
3173 strcpy (VarIdStr[1], Name);
3174 strcat (VarIdStr[1], ".Minute");
3175 }
3176 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
3177 if (VarIdStr[2] != NULL) {
3178 strcpy (VarIdStr[2], Name);
3179 strcat (VarIdStr[2], ".Second");
3180 }
3181 }
3182
3183 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
3184 goto Err;
3185 }
3186 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
3187 goto Err;
3188 }
3189 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
3190 goto Err;
3191 }
3192
3193 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3194 QuestionId = GetFreeQuestionId ();
3195 } else {
3196 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3197 goto Err;
3198 }
3199 MarkQuestionIdUsed (QuestionId);
3200 }
3201
3202 pNode[0]->mQuestionId = QuestionId;
3203 pNode[1]->mQuestionId = QuestionId;
3204 pNode[2]->mQuestionId = QuestionId;
3205 pNode[0]->mQtype = QUESTION_TIME;
3206 pNode[1]->mQtype = QUESTION_TIME;
3207 pNode[2]->mQtype = QUESTION_TIME;
3208 pNode[0]->mNext = pNode[1];
3209 pNode[1]->mNext = pNode[2];
3210 pNode[2]->mNext = mQuestionList;
3211 mQuestionList = pNode[0];
3212
3213 for (Index = 0; Index < 3; Index++) {
3214 if (VarIdStr[Index] != NULL) {
3215 delete[] VarIdStr[Index];
3216 VarIdStr[Index] = NULL;
3217 }
3218 }
3219
3220 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3221 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3222 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3223
3224 return;
3225
3226 Err:
3227 for (Index = 0; Index < 3; Index++) {
3228 if (pNode[Index] != NULL) {
3229 delete pNode[Index];
3230 }
3231
3232 if (VarIdStr[Index] != NULL) {
3233 delete[] VarIdStr[Index];
3234 VarIdStr[Index] = NULL;
3235 }
3236 }
3237 }
3238
3239 VOID
3240 CVfrQuestionDB::RegisterRefQuestion (
3241 IN CHAR8 *Name,
3242 IN CHAR8 *BaseVarId,
3243 IN OUT EFI_QUESTION_ID &QuestionId
3244 )
3245 {
3246 SVfrQuestionNode *pNode[4] = {NULL, };
3247 UINT32 Len;
3248 CHAR8 *VarIdStr[4] = {NULL, };
3249 CHAR8 Index;
3250
3251 if (BaseVarId == NULL && Name == NULL) {
3252 return;
3253 }
3254
3255 if (BaseVarId != NULL) {
3256 Len = strlen (BaseVarId);
3257
3258 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3259 if (VarIdStr[0] != NULL) {
3260 strcpy (VarIdStr[0], BaseVarId);
3261 strcat (VarIdStr[0], ".QuestionId");
3262 }
3263 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3264 if (VarIdStr[1] != NULL) {
3265 strcpy (VarIdStr[1], BaseVarId);
3266 strcat (VarIdStr[1], ".FormId");
3267 }
3268 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3269 if (VarIdStr[2] != NULL) {
3270 strcpy (VarIdStr[2], BaseVarId);
3271 strcat (VarIdStr[2], ".FormSetGuid");
3272 }
3273 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3274 if (VarIdStr[3] != NULL) {
3275 strcpy (VarIdStr[3], BaseVarId);
3276 strcat (VarIdStr[3], ".DevicePath");
3277 }
3278 } else {
3279 Len = strlen (Name);
3280
3281 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3282 if (VarIdStr[0] != NULL) {
3283 strcpy (VarIdStr[0], Name);
3284 strcat (VarIdStr[0], ".QuestionId");
3285 }
3286 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3287 if (VarIdStr[1] != NULL) {
3288 strcpy (VarIdStr[1], Name);
3289 strcat (VarIdStr[1], ".FormId");
3290 }
3291 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3292 if (VarIdStr[2] != NULL) {
3293 strcpy (VarIdStr[2], Name);
3294 strcat (VarIdStr[2], ".FormSetGuid");
3295 }
3296 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3297 if (VarIdStr[3] != NULL) {
3298 strcpy (VarIdStr[3], Name);
3299 strcat (VarIdStr[3], ".DevicePath");
3300 }
3301 }
3302
3303 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
3304 goto Err;
3305 }
3306 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
3307 goto Err;
3308 }
3309 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
3310 goto Err;
3311 }
3312 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
3313 goto Err;
3314 }
3315
3316 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3317 QuestionId = GetFreeQuestionId ();
3318 } else {
3319 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3320 goto Err;
3321 }
3322 MarkQuestionIdUsed (QuestionId);
3323 }
3324
3325 pNode[0]->mQuestionId = QuestionId;
3326 pNode[1]->mQuestionId = QuestionId;
3327 pNode[2]->mQuestionId = QuestionId;
3328 pNode[3]->mQuestionId = QuestionId;
3329 pNode[0]->mQtype = QUESTION_REF;
3330 pNode[1]->mQtype = QUESTION_REF;
3331 pNode[2]->mQtype = QUESTION_REF;
3332 pNode[3]->mQtype = QUESTION_REF;
3333 pNode[0]->mNext = pNode[1];
3334 pNode[1]->mNext = pNode[2];
3335 pNode[2]->mNext = pNode[3];
3336 pNode[3]->mNext = mQuestionList;
3337 mQuestionList = pNode[0];
3338
3339 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3340 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3341 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3342 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3343
3344 return;
3345
3346 Err:
3347 for (Index = 0; Index < 4; Index++) {
3348 if (pNode[Index] != NULL) {
3349 delete pNode[Index];
3350 }
3351
3352 if (VarIdStr[Index] != NULL) {
3353 delete VarIdStr[Index];
3354 }
3355 }
3356 }
3357
3358 EFI_VFR_RETURN_CODE
3359 CVfrQuestionDB::UpdateQuestionId (
3360 IN EFI_QUESTION_ID QId,
3361 IN EFI_QUESTION_ID NewQId
3362 )
3363 {
3364 SVfrQuestionNode *pNode = NULL;
3365
3366 if (QId == NewQId) {
3367 // don't update
3368 return VFR_RETURN_SUCCESS;
3369 }
3370
3371 //
3372 // For Framework Vfr, don't check question ID conflict.
3373 //
3374 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
3375 return VFR_RETURN_REDEFINED;
3376 }
3377
3378 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3379 if (pNode->mQuestionId == QId) {
3380 break;
3381 }
3382 }
3383
3384 if (pNode == NULL) {
3385 return VFR_RETURN_UNDEFINED;
3386 }
3387
3388 MarkQuestionIdUnused (QId);
3389 pNode->mQuestionId = NewQId;
3390 MarkQuestionIdUsed (NewQId);
3391
3392 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
3393
3394 return VFR_RETURN_SUCCESS;
3395 }
3396
3397 VOID
3398 CVfrQuestionDB::GetQuestionId (
3399 IN CHAR8 *Name,
3400 IN CHAR8 *VarIdStr,
3401 OUT EFI_QUESTION_ID &QuestionId,
3402 OUT UINT32 &BitMask,
3403 OUT EFI_QUESION_TYPE *QType
3404 )
3405 {
3406 SVfrQuestionNode *pNode;
3407
3408 QuestionId = EFI_QUESTION_ID_INVALID;
3409 BitMask = 0x00000000;
3410 if (QType != NULL) {
3411 *QType = QUESTION_NORMAL;
3412 }
3413
3414 if ((Name == NULL) && (VarIdStr == NULL)) {
3415 return ;
3416 }
3417
3418 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3419 if (Name != NULL) {
3420 if (strcmp (pNode->mName, Name) != 0) {
3421 continue;
3422 }
3423 }
3424
3425 if (VarIdStr != NULL) {
3426 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
3427 continue;
3428 }
3429 }
3430
3431 QuestionId = pNode->mQuestionId;
3432 BitMask = pNode->mBitMask;
3433 if (QType != NULL) {
3434 *QType = pNode->mQtype;
3435 }
3436 break;
3437 }
3438
3439 return ;
3440 }
3441
3442 EFI_VFR_RETURN_CODE
3443 CVfrQuestionDB::FindQuestion (
3444 IN EFI_QUESTION_ID QuestionId
3445 )
3446 {
3447 SVfrQuestionNode *pNode;
3448
3449 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3450 return VFR_RETURN_INVALID_PARAMETER;
3451 }
3452
3453 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3454 if (pNode->mQuestionId == QuestionId) {
3455 return VFR_RETURN_SUCCESS;
3456 }
3457 }
3458
3459 return VFR_RETURN_UNDEFINED;
3460 }
3461
3462 EFI_VFR_RETURN_CODE
3463 CVfrQuestionDB::FindQuestion (
3464 IN CHAR8 *Name
3465 )
3466 {
3467 SVfrQuestionNode *pNode;
3468
3469 if (Name == NULL) {
3470 return VFR_RETURN_FATAL_ERROR;
3471 }
3472
3473 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3474 if (strcmp (pNode->mName, Name) == 0) {
3475 return VFR_RETURN_SUCCESS;
3476 }
3477 }
3478
3479 return VFR_RETURN_UNDEFINED;
3480 }
3481
3482 CVfrStringDB::CVfrStringDB ()
3483 {
3484 mStringFileName = NULL;
3485 }
3486
3487 CVfrStringDB::~CVfrStringDB ()
3488 {
3489 if (mStringFileName != NULL) {
3490 delete[] mStringFileName;
3491 }
3492 mStringFileName = NULL;
3493 }
3494
3495
3496 VOID
3497 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
3498 {
3499 UINT32 FileLen = 0;
3500
3501 if (StringFileName == NULL) {
3502 return;
3503 }
3504
3505 if (mStringFileName != NULL) {
3506 delete[] mStringFileName;
3507 }
3508
3509 FileLen = strlen (StringFileName) + 1;
3510 mStringFileName = new CHAR8[FileLen];
3511 if (mStringFileName == NULL) {
3512 return;
3513 }
3514
3515 strcpy (mStringFileName, StringFileName);
3516 mStringFileName[FileLen - 1] = '\0';
3517 }
3518
3519
3520 /**
3521 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3522 from a set of supported languages.
3523
3524 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3525 contains a set of language codes.
3526 @param[in] Language A variable that contains pointers to Null-terminated
3527 ASCII strings that contain one language codes.
3528
3529 @retval FALSE The best matching language could not be found in SupportedLanguages.
3530 @retval TRUE The best matching language could be found in SupportedLanguages.
3531
3532 **/
3533 BOOLEAN
3534 CVfrStringDB::GetBestLanguage (
3535 IN CONST CHAR8 *SupportedLanguages,
3536 IN CHAR8 *Language
3537 )
3538 {
3539 UINTN CompareLength;
3540 UINTN LanguageLength;
3541 CONST CHAR8 *Supported;
3542
3543 if (SupportedLanguages == NULL || Language == NULL){
3544 return FALSE;
3545 }
3546
3547 //
3548 // Determine the length of the first RFC 4646 language code in Language
3549 //
3550 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
3551
3552 //
3553 // Trim back the length of Language used until it is empty
3554 //
3555 while (LanguageLength > 0) {
3556 //
3557 // Loop through all language codes in SupportedLanguages
3558 //
3559 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
3560 //
3561 // Skip ';' characters in Supported
3562 //
3563 for (; *Supported != '\0' && *Supported == ';'; Supported++);
3564 //
3565 // Determine the length of the next language code in Supported
3566 //
3567 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
3568 //
3569 // If Language is longer than the Supported, then skip to the next language
3570 //
3571 if (LanguageLength > CompareLength) {
3572 continue;
3573 }
3574
3575 //
3576 // See if the first LanguageLength characters in Supported match Language
3577 //
3578 if (strncmp (Supported, Language, LanguageLength) == 0) {
3579 return TRUE;
3580 }
3581 }
3582
3583 //
3584 // Trim Language from the right to the next '-' character
3585 //
3586 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
3587 }
3588
3589 //
3590 // No matches were found
3591 //
3592 return FALSE;
3593 }
3594
3595
3596 CHAR8 *
3597 CVfrStringDB::GetVarStoreNameFormStringId (
3598 IN EFI_STRING_ID StringId
3599 )
3600 {
3601 FILE *pInFile = NULL;
3602 UINT32 NameOffset;
3603 UINT32 Length;
3604 UINT8 *StringPtr;
3605 CHAR8 *StringName;
3606 CHAR16 *UnicodeString;
3607 CHAR8 *VarStoreName = NULL;
3608 CHAR8 *DestTmp;
3609 UINT8 *Current;
3610 EFI_STATUS Status;
3611 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
3612 UINT8 BlockType;
3613 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
3614
3615 if (mStringFileName == NULL) {
3616 return NULL;
3617 }
3618
3619 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
3620 return NULL;
3621 }
3622
3623 //
3624 // Get file length.
3625 //
3626 fseek (pInFile, 0, SEEK_END);
3627 Length = ftell (pInFile);
3628 fseek (pInFile, 0, SEEK_SET);
3629
3630 //
3631 // Get file data.
3632 //
3633 StringPtr = new UINT8[Length];
3634 if (StringPtr == NULL) {
3635 fclose (pInFile);
3636 return NULL;
3637 }
3638 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
3639 fclose (pInFile);
3640
3641 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3642 //
3643 // Check the String package.
3644 //
3645 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
3646 delete[] StringPtr;
3647 return NULL;
3648 }
3649
3650 //
3651 // Search the language, get best language base on RFC 4647 matching algorithm.
3652 //
3653 Current = StringPtr;
3654 while (!GetBestLanguage ("en", PkgHeader->Language)) {
3655 Current += PkgHeader->Header.Length;
3656 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
3657 //
3658 // If can't find string package base on language, just return the first string package.
3659 //
3660 if (Current - StringPtr >= Length) {
3661 Current = StringPtr;
3662 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3663 break;
3664 }
3665 }
3666
3667 Current += PkgHeader->HdrSize;
3668 //
3669 // Find the string block according the stringId.
3670 //
3671 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
3672 if (Status != EFI_SUCCESS) {
3673 delete[] StringPtr;
3674 return NULL;
3675 }
3676
3677 //
3678 // Get varstore name according the string type.
3679 //
3680 switch (BlockType) {
3681 case EFI_HII_SIBT_STRING_SCSU:
3682 case EFI_HII_SIBT_STRING_SCSU_FONT:
3683 case EFI_HII_SIBT_STRINGS_SCSU:
3684 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3685 StringName = (CHAR8*)(Current + NameOffset);
3686 VarStoreName = new CHAR8[strlen(StringName) + 1];
3687 strcpy (VarStoreName, StringName);
3688 break;
3689 case EFI_HII_SIBT_STRING_UCS2:
3690 case EFI_HII_SIBT_STRING_UCS2_FONT:
3691 case EFI_HII_SIBT_STRINGS_UCS2:
3692 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3693 UnicodeString = (CHAR16*)(Current + NameOffset);
3694 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
3695 DestTmp = new CHAR8[Length / 2 + 1];
3696 VarStoreName = DestTmp;
3697 while (*UnicodeString != '\0') {
3698 *(DestTmp++) = (CHAR8) *(UnicodeString++);
3699 }
3700 *DestTmp = '\0';
3701 break;
3702 default:
3703 break;
3704 }
3705
3706 delete[] StringPtr;
3707
3708 return VarStoreName;
3709 }
3710
3711 EFI_STATUS
3712 CVfrStringDB::FindStringBlock (
3713 IN UINT8 *StringData,
3714 IN EFI_STRING_ID StringId,
3715 OUT UINT32 *StringTextOffset,
3716 OUT UINT8 *BlockType
3717 )
3718 {
3719 UINT8 *BlockHdr;
3720 EFI_STRING_ID CurrentStringId;
3721 UINT32 BlockSize;
3722 UINT32 Index;
3723 UINT8 *StringTextPtr;
3724 UINT32 Offset;
3725 UINT16 StringCount;
3726 UINT16 SkipCount;
3727 UINT8 Length8;
3728 EFI_HII_SIBT_EXT2_BLOCK Ext2;
3729 UINT32 Length32;
3730 UINT32 StringSize;
3731
3732 CurrentStringId = 1;
3733
3734 //
3735 // Parse the string blocks to get the string text and font.
3736 //
3737 BlockHdr = StringData;
3738 BlockSize = 0;
3739 Offset = 0;
3740 while (*BlockHdr != EFI_HII_SIBT_END) {
3741 switch (*BlockHdr) {
3742 case EFI_HII_SIBT_STRING_SCSU:
3743 Offset = sizeof (EFI_HII_STRING_BLOCK);
3744 StringTextPtr = BlockHdr + Offset;
3745 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3746 CurrentStringId++;
3747 break;
3748
3749 case EFI_HII_SIBT_STRING_SCSU_FONT:
3750 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
3751 StringTextPtr = BlockHdr + Offset;
3752 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3753 CurrentStringId++;
3754 break;
3755
3756 case EFI_HII_SIBT_STRINGS_SCSU:
3757 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3758 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
3759 BlockSize += StringTextPtr - BlockHdr;
3760
3761 for (Index = 0; Index < StringCount; Index++) {
3762 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3763 if (CurrentStringId == StringId) {
3764 *BlockType = *BlockHdr;
3765 *StringTextOffset = StringTextPtr - StringData;
3766 return EFI_SUCCESS;
3767 }
3768 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3769 CurrentStringId++;
3770 }
3771 break;
3772
3773 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3774 memcpy (
3775 &StringCount,
3776 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3777 sizeof (UINT16)
3778 );
3779 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
3780 BlockSize += StringTextPtr - BlockHdr;
3781
3782 for (Index = 0; Index < StringCount; Index++) {
3783 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3784 if (CurrentStringId == StringId) {
3785 *BlockType = *BlockHdr;
3786 *StringTextOffset = StringTextPtr - StringData;
3787 return EFI_SUCCESS;
3788 }
3789 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3790 CurrentStringId++;
3791 }
3792 break;
3793
3794 case EFI_HII_SIBT_STRING_UCS2:
3795 Offset = sizeof (EFI_HII_STRING_BLOCK);
3796 StringTextPtr = BlockHdr + Offset;
3797 //
3798 // Use StringSize to store the size of the specified string, including the NULL
3799 // terminator.
3800 //
3801 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3802 BlockSize += Offset + StringSize;
3803 CurrentStringId++;
3804 break;
3805
3806 case EFI_HII_SIBT_STRING_UCS2_FONT:
3807 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3808 StringTextPtr = BlockHdr + Offset;
3809 //
3810 // Use StrSize to store the size of the specified string, including the NULL
3811 // terminator.
3812 //
3813 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3814 BlockSize += Offset + StringSize;
3815 CurrentStringId++;
3816 break;
3817
3818 case EFI_HII_SIBT_STRINGS_UCS2:
3819 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
3820 StringTextPtr = BlockHdr + Offset;
3821 BlockSize += Offset;
3822 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3823 for (Index = 0; Index < StringCount; Index++) {
3824 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3825 BlockSize += StringSize;
3826 if (CurrentStringId == StringId) {
3827 *BlockType = *BlockHdr;
3828 *StringTextOffset = StringTextPtr - StringData;
3829 return EFI_SUCCESS;
3830 }
3831 StringTextPtr = StringTextPtr + StringSize;
3832 CurrentStringId++;
3833 }
3834 break;
3835
3836 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3837 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3838 StringTextPtr = BlockHdr + Offset;
3839 BlockSize += Offset;
3840 memcpy (
3841 &StringCount,
3842 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3843 sizeof (UINT16)
3844 );
3845 for (Index = 0; Index < StringCount; Index++) {
3846 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3847 BlockSize += StringSize;
3848 if (CurrentStringId == StringId) {
3849 *BlockType = *BlockHdr;
3850 *StringTextOffset = StringTextPtr - StringData;
3851 return EFI_SUCCESS;
3852 }
3853 StringTextPtr = StringTextPtr + StringSize;
3854 CurrentStringId++;
3855 }
3856 break;
3857
3858 case EFI_HII_SIBT_DUPLICATE:
3859 if (CurrentStringId == StringId) {
3860 //
3861 // Incoming StringId is an id of a duplicate string block.
3862 // Update the StringId to be the previous string block.
3863 // Go back to the header of string block to search.
3864 //
3865 memcpy (
3866 &StringId,
3867 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
3868 sizeof (EFI_STRING_ID)
3869 );
3870 CurrentStringId = 1;
3871 BlockSize = 0;
3872 } else {
3873 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
3874 CurrentStringId++;
3875 }
3876 break;
3877
3878 case EFI_HII_SIBT_SKIP1:
3879 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
3880 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3881 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
3882 break;
3883
3884 case EFI_HII_SIBT_SKIP2:
3885 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3886 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3887 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
3888 break;
3889
3890 case EFI_HII_SIBT_EXT1:
3891 memcpy (
3892 &Length8,
3893 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3894 sizeof (UINT8)
3895 );
3896 BlockSize += Length8;
3897 break;
3898
3899 case EFI_HII_SIBT_EXT2:
3900 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
3901 BlockSize += Ext2.Length;
3902 break;
3903
3904 case EFI_HII_SIBT_EXT4:
3905 memcpy (
3906 &Length32,
3907 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3908 sizeof (UINT32)
3909 );
3910
3911 BlockSize += Length32;
3912 break;
3913
3914 default:
3915 break;
3916 }
3917
3918 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
3919 *StringTextOffset = BlockHdr - StringData + Offset;
3920 *BlockType = *BlockHdr;
3921
3922 if (StringId == CurrentStringId - 1) {
3923 //
3924 // if only one skip item, return EFI_NOT_FOUND.
3925 //
3926 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
3927 return EFI_NOT_FOUND;
3928 } else {
3929 return EFI_SUCCESS;
3930 }
3931 }
3932
3933 if (StringId < CurrentStringId - 1) {
3934 return EFI_NOT_FOUND;
3935 }
3936 }
3937 BlockHdr = StringData + BlockSize;
3938 }
3939
3940 return EFI_NOT_FOUND;
3941 }
3942
3943 UINT32
3944 CVfrStringDB::GetUnicodeStringTextSize (
3945 IN UINT8 *StringSrc
3946 )
3947 {
3948 UINT32 StringSize;
3949 CHAR16 *StringPtr;
3950
3951 StringSize = sizeof (CHAR16);
3952 StringPtr = (UINT16*)StringSrc;
3953 while (*StringPtr++ != L'\0') {
3954 StringSize += sizeof (CHAR16);
3955 }
3956
3957 return StringSize;
3958 }
3959
3960 BOOLEAN VfrCompatibleMode = FALSE;
3961
3962 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
3963 CVfrDefaultStore gCVfrDefaultStore;
3964 CVfrDataStorage gCVfrDataStorage;
3965
3966