]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiVfrCompile / VfrUtilityLib.cpp
1 #include "stdio.h"
2 #include "stdlib.h"
3 #include "VfrUtilityLib.h"
4 #include "VfrFormPkg.h"
5
6 VOID
7 CVfrBinaryOutput::WriteLine (
8 IN FILE *pFile,
9 IN UINT32 LineBytes,
10 IN INT8 *LineHeader,
11 IN INT8 *BlkBuf,
12 IN UINT32 BlkSize
13 )
14 {
15 UINT32 Index;
16
17 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
18 return;
19 }
20
21 for (Index = 0; Index < BlkSize; Index++) {
22 if ((Index % LineBytes) == 0) {
23 fprintf (pFile, "\n%s", LineHeader);
24 }
25 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
26 }
27 }
28
29 VOID
30 CVfrBinaryOutput::WriteEnd (
31 IN FILE *pFile,
32 IN UINT32 LineBytes,
33 IN INT8 *LineHeader,
34 IN INT8 *BlkBuf,
35 IN UINT32 BlkSize
36 )
37 {
38 UINT32 Index;
39
40 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
41 return;
42 }
43
44 for (Index = 0; Index < BlkSize - 1; Index++) {
45 if ((Index % LineBytes) == 0) {
46 fprintf (pFile, "\n%s", LineHeader);
47 }
48 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
49 }
50
51 if ((Index % LineBytes) == 0) {
52 fprintf (pFile, "\n%s", LineHeader);
53 }
54 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
55 }
56
57 SConfigInfo::SConfigInfo (
58 IN UINT8 Type,
59 IN UINT16 Offset,
60 IN UINT32 Width,
61 IN EFI_IFR_TYPE_VALUE Value
62 )
63 {
64 mOffset = Offset;
65 mWidth = (UINT16)Width;
66 mValue = new UINT8[mWidth];
67 if (mValue == NULL) {
68 return;
69 }
70
71 switch (Type) {
72 case EFI_IFR_TYPE_NUM_SIZE_8 :
73 memcpy (mValue, &Value.u8, mWidth);
74 break;
75 case EFI_IFR_TYPE_NUM_SIZE_16 :
76 memcpy (mValue, &Value.u16, mWidth);
77 break;
78 case EFI_IFR_TYPE_NUM_SIZE_32 :
79 memcpy (mValue, &Value.u32, mWidth);
80 break;
81 case EFI_IFR_TYPE_NUM_SIZE_64 :
82 memcpy (mValue, &Value.u64, mWidth);
83 break;
84 case EFI_IFR_TYPE_BOOLEAN :
85 memcpy (mValue, &Value.b, mWidth);
86 break;
87 case EFI_IFR_TYPE_TIME :
88 memcpy (mValue, &Value.time, mWidth);
89 break;
90 case EFI_IFR_TYPE_DATE :
91 memcpy (mValue, &Value.date, mWidth);
92 break;
93 case EFI_IFR_TYPE_STRING :
94 memcpy (mValue, &Value.string, mWidth);
95 break;
96 case EFI_IFR_TYPE_OTHER :
97 return;
98 }
99 }
100
101 SConfigInfo::~SConfigInfo (
102 VOID
103 )
104 {
105 BUFFER_SAFE_FREE (mValue);
106 }
107
108 SConfigItem::SConfigItem (
109 IN INT8 *Id,
110 IN INT8 *Info
111 )
112 {
113 mId = NULL;
114 mInfo = NULL;
115 mInfoStrList = NULL;
116 mNext = NULL;
117
118 if (Id != NULL) {
119 if ((mId = new INT8[strlen (Id) + 1]) != NULL) {
120 strcpy (mId, Id);
121 }
122 }
123
124 if (Info != NULL) {
125 if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {
126 strcpy (mInfo, Info);
127 }
128 }
129 }
130
131 SConfigItem::SConfigItem (
132 IN INT8 *Id,
133 IN INT8 *Info,
134 IN UINT8 Type,
135 IN UINT16 Offset,
136 IN UINT16 Width,
137 IN EFI_IFR_TYPE_VALUE Value
138 )
139 {
140 mId = NULL;
141 mInfo = NULL;
142 mInfoStrList = NULL;
143 mNext = NULL;
144
145 if (Id != NULL) {
146 if ((mId = new INT8[strlen (Id) + 1]) != NULL) {
147 strcpy (mId, Id);
148 }
149 }
150
151 if (Info != NULL) {
152 if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {
153 strcpy (mInfo, Info);
154 }
155 }
156
157 mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
158 }
159
160 SConfigItem::~SConfigItem (
161 VOID
162 )
163 {
164 SConfigInfo *Info;
165
166 BUFFER_SAFE_FREE (mId);
167 BUFFER_SAFE_FREE (mInfo);
168 while (mInfoStrList != NULL) {
169 Info = mInfoStrList;
170 mInfoStrList = mInfoStrList->mNext;
171
172 BUFFER_SAFE_FREE (Info);
173 }
174 }
175
176 UINT8
177 CVfrBufferConfig::Register (
178 IN INT8 *Id,
179 IN INT8 *Info
180 )
181 {
182 SConfigItem *pNew;
183
184 if (Select (Id) == 0) {
185 return 1;
186 }
187
188 if ((pNew = new SConfigItem (Id, Info)) == NULL) {
189 return 2;
190 }
191 if (mItemListHead == NULL) {
192 mItemListHead = pNew;
193 mItemListTail = pNew;
194 } else {
195 mItemListTail->mNext = pNew;
196 mItemListTail = pNew;
197 }
198 mItemListPos = pNew;
199
200 return 0;
201 }
202
203 VOID
204 CVfrBufferConfig::Open (
205 VOID
206 )
207 {
208 mItemListPos = mItemListHead;
209 }
210
211 BOOLEAN
212 CVfrBufferConfig::Eof(
213 VOID
214 )
215 {
216 return (mItemListPos == NULL) ? TRUE : FALSE;
217 }
218
219 UINT8
220 CVfrBufferConfig::Select (
221 IN INT8 *Id,
222 IN INT8 *Info
223 )
224 {
225 SConfigItem *p;
226
227 if (Id == NULL) {
228 mItemListPos = mItemListHead;
229 return 0;
230 } else {
231 for (p = mItemListHead; p != NULL; p = p->mNext) {
232 if (strcmp (p->mId, Id) != 0) {
233 continue;
234 }
235
236 if ((p->mInfo != NULL) && (Info != NULL)) {
237 if (strcmp (p->mInfo, Info) != 0) {
238 continue;
239 }
240 }
241
242 mItemListPos = p;
243 return 0;
244 }
245 }
246
247 return 1;
248 }
249
250 UINT8
251 CVfrBufferConfig::Write (
252 IN CONST CHAR8 Mode,
253 IN INT8 *Id,
254 IN INT8 *Info,
255 IN UINT8 Type,
256 IN UINT16 Offset,
257 IN UINT32 Width,
258 IN EFI_IFR_TYPE_VALUE Value
259 )
260 {
261 UINT8 Ret;
262 SConfigItem *pItem;
263 SConfigInfo *pInfo;
264
265 switch (Mode) {
266 case 'a' : // add
267 if (Select (Id) == 0) {
268 if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
269 return 2;
270 }
271 pInfo->mNext = mItemListPos->mInfoStrList;
272 mItemListPos->mInfoStrList = pInfo;
273 } else {
274 if ((pItem = new SConfigItem (Id, Info, Type, Offset, Width, Value)) == NULL) {
275 return 2;
276 }
277 if (mItemListHead == NULL) {
278 mItemListHead = pItem;
279 mItemListTail = pItem;
280 } else {
281 mItemListTail->mNext = pItem;
282 mItemListTail = pItem;
283 }
284 mItemListPos = pItem;
285 }
286 break;
287
288 case 'd' : // delete
289 if ((Ret = Select (Id)) != 0) {
290 return Ret;
291 }
292
293 if (mItemListHead == mItemListPos) {
294 mItemListHead = mItemListPos->mNext;
295 delete mItemListPos;
296 break;
297 }
298
299 for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
300 ;
301
302 pItem->mNext = mItemListPos->mNext;
303 if (mItemListTail == mItemListPos) {
304 mItemListTail = pItem;
305 }
306 delete mItemListPos;
307 mItemListPos = pItem->mNext;
308 break;
309
310 case 'i' : // set info
311 if ((Ret = Select (Id)) != 0) {
312 return Ret;
313 }
314 if (mItemListPos->mInfo != NULL) {
315 delete mItemListPos->mInfo;
316 }
317 mItemListPos->mInfo = NULL;
318 if (Info != NULL) {
319 if ((mItemListPos->mInfo = new INT8[strlen (Info) + 1]) == NULL) {
320 return 2;
321 }
322 strcpy (mItemListPos->mInfo, Info);
323 }
324 break;
325
326 default :
327 return 1;
328 }
329
330 return 0;
331 }
332
333 #if 0
334 UINT8
335 CVfrBufferConfig::ReadId (
336 OUT INT8 **Id,
337 OUT INT8 **Info
338 )
339 {
340 if (mInfoStrItemListPos == NULL) {
341 return 1; // end read or some error occur
342 }
343
344 if (Id != NULL) {
345 *Id = new INT8 (strlen (mInfoStrItemListPos->mId + 1));
346 strcpy (*Id, mInfoStrItemListPos->mId);
347 }
348 if (Info != NULL) {
349 *Info = new INT8 (strlen (mInfoStrItemListPos->mInfo + 1));
350 strcpy (*Info, mInfoStrItemListPos->mInfo);
351 }
352
353 return 0;
354 }
355
356 UINT8
357 CVfrBufferConfig::ReadInfo (
358 IN INT8 *Id,
359 IN UINT32 Index,
360 IN OUT UINT32 &Number,
361 OUT INT8 *Offset,
362 OUT INT8 *Width,
363 OUT INT8 *Value
364 )
365 {
366 UINT8 ret;
367 SConfigInfo *p;
368 UINT32 idx;
369 UINT32 num;
370
371 if (Id != NULL) {
372 if ((ret = Select (Id)) != 0) {
373 return ret;
374 }
375 }
376
377 if (mInfoStrItemListPos == NULL) {
378 return 1; // end read or some error occur
379 }
380
381 p = mInfoStrItemListPos->mInfoStrList;
382 for (idx = 0; (idx < Index) && (p != NULL); idx++) {
383 p = p->mNext;
384 }
385 if (p == NULL) {
386 return 1;
387 }
388
389 if (Offset != NULL) {
390 Offset[0] = '\0';
391 }
392 if (Width != NULL) {
393 Width[0] = '\0';
394 }
395 if (Value != NULL) {
396 Value[0] = '\0';
397 }
398
399 while (num < Number) {
400 if (Offset != NULL) {
401 strcat (Offset, p->mOffset);
402 }
403 if (Width != NULL) {
404 strcat (Width, p->mWidth);
405 }
406 if (Value != NULL) {
407 strcat (Value, p->mValue);
408 }
409
410 num++;
411 if ((p = p->mNext) == NULL) {
412 break;
413 }
414 }
415 Number = num;
416
417 return 0;
418 }
419
420 VOID
421 CVfrBufferConfig::ReadNext (
422 VOID
423 )
424 {
425 if (mItemListPos != NULL) {
426 mItemListPos = mItemListPos->mNext;
427 }
428 }
429 #endif
430
431 VOID
432 CVfrBufferConfig::Close (
433 VOID
434 )
435 {
436 mItemListPos = NULL;
437 }
438
439 #define BYTES_PRE_LINE 0x10
440
441 VOID
442 CVfrBufferConfig::OutputCFile (
443 IN FILE *pFile,
444 IN INT8 *BaseName
445 )
446 {
447 CVfrBinaryOutput Output;
448 SConfigItem *Item;
449 SConfigInfo *Info;
450 UINT32 TotalLen;
451
452 if (pFile == NULL) {
453 return;
454 }
455
456 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
457 if (Item->mInfoStrList != NULL) {
458 fprintf (pFile, "\nunsigned char %s%sDefault%04x[] = {", BaseName, Item->mId, Item->mInfo);
459
460 TotalLen = sizeof (UINT32);
461 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
462 TotalLen += Info->mWidth + sizeof (UINT16) * 2;
463 }
464 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&TotalLen, sizeof (UINT32));
465
466 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
467 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mOffset, sizeof (UINT16));
468 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mWidth, sizeof (UINT16));
469 if (Info->mNext == NULL) {
470 Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth);
471 } else {
472 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth);
473 }
474 fprintf (pFile, "\n");
475 }
476 fprintf (pFile, "};\n");
477 }
478 }
479 }
480
481 CVfrBufferConfig::CVfrBufferConfig (
482 VOID
483 )
484 {
485 mItemListHead = NULL;
486 mItemListTail = NULL;
487 mItemListPos = NULL;
488 }
489
490 CVfrBufferConfig::~CVfrBufferConfig (
491 VOID
492 )
493 {
494 SConfigItem *p;
495
496 while (mItemListHead != NULL) {
497 p = mItemListHead;
498 mItemListHead = mItemListHead->mNext;
499 delete p;
500 }
501
502 mItemListHead = NULL;
503 mItemListTail = NULL;
504 mItemListPos = NULL;
505 }
506
507 CVfrBufferConfig gCVfrBufferConfig;
508
509 static struct {
510 INT8 *mTypeName;
511 UINT8 mType;
512 UINT32 mSize;
513 UINT32 mAlign;
514 } gInternalTypesTable [] = {
515 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},
516 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},
517 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},
518 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},
519 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},
520 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT8)},
521 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
522 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
523 {NULL, EFI_IFR_TYPE_OTHER, 0, 0}
524 };
525
526 STATIC
527 BOOLEAN
528 _IS_INTERNAL_TYPE (
529 IN INT8 *TypeName
530 )
531 {
532 UINT32 Index;
533
534 if (TypeName == NULL) {
535 return FALSE;
536 }
537
538 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
539 if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
540 return TRUE;
541 }
542 }
543
544 return FALSE;
545 }
546
547 STATIC
548 INT8 *
549 TrimHex (
550 IN INT8 *Str,
551 OUT bool *IsHex
552 )
553 {
554 *IsHex = FALSE;
555
556 while (*Str && *Str == ' ') {
557 Str++;
558 }
559 while (*Str && *Str == '0') {
560 Str++;
561 }
562 if (*Str && (*Str == 'x' || *Str == 'X')) {
563 Str++;
564 *IsHex = TRUE;
565 }
566
567 return Str;
568 }
569
570 UINT32
571 _STR2U32 (
572 IN INT8 *Str
573 )
574 {
575 bool IsHex;
576 UINT32 Value;
577 INT8 c;
578
579 Str = TrimHex (Str, &IsHex);
580 for (Value = 0; (c = *Str) != '\0'; Str++) {
581 //
582 // BUG: does not handle overflow here
583 //
584 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
585
586 if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
587 Value += (c - 'a' + 10);
588 }
589 if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
590 Value += (c - 'A' + 10);
591 }
592 if (c >= '0' && c <= '9') {
593 Value += (c - '0');
594 }
595 }
596
597 return Value;
598 }
599
600 VOID
601 CVfrVarDataTypeDB::RegisterNewType (
602 IN SVfrDataType *New
603 )
604 {
605 New->mNext = mDataTypeList;
606 mDataTypeList = New;
607 }
608
609 EFI_VFR_RETURN_CODE
610 CVfrVarDataTypeDB::ExtractStructTypeName (
611 IN INT8 *&VarStr,
612 OUT INT8 *TName
613 )
614 {
615 if (TName == NULL) {
616 return VFR_RETURN_FATAL_ERROR;
617 }
618
619 while((*VarStr != '\0') && (*VarStr != '.')) {
620 *TName = *VarStr;
621 VarStr++;
622 TName++;
623 }
624 *TName = '\0';
625 if (*VarStr == '.') {
626 VarStr++;
627 }
628
629 return VFR_RETURN_SUCCESS;
630 }
631
632 EFI_VFR_RETURN_CODE
633 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
634 IN INT8 *&VarStr,
635 IN INT8 *FName,
636 OUT UINT32 &ArrayIdx
637 )
638 {
639 UINT32 Idx;
640 INT8 ArrayStr[MAX_NAME_LEN + 1];
641
642 ArrayIdx = INVALID_ARRAY_INDEX;
643
644 if (FName == NULL) {
645 return VFR_RETURN_FATAL_ERROR;
646 }
647
648 while((*VarStr != '\0') &&
649 (*VarStr != '.') &&
650 (*VarStr != '[') &&
651 (*VarStr != ']')) {
652 *FName = *VarStr;
653 VarStr++;
654 FName++;
655 }
656 *FName = '\0';
657
658 switch (*VarStr) {
659 case '.' :
660 VarStr++;
661 case '\0':
662 return VFR_RETURN_SUCCESS;
663 case '[' :
664 VarStr++;
665 for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
666 ArrayStr[Idx] = *VarStr;
667 }
668 ArrayStr[Idx] = '\0';
669
670 if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
671 return VFR_RETURN_DATA_STRING_ERROR;
672 }
673 ArrayIdx = _STR2U32 (ArrayStr);
674 if (*VarStr == ']') {
675 VarStr++;
676 }
677 return VFR_RETURN_SUCCESS;
678 case ']':
679 return VFR_RETURN_DATA_STRING_ERROR;
680 }
681
682 return VFR_RETURN_SUCCESS;
683 }
684
685 EFI_VFR_RETURN_CODE
686 CVfrVarDataTypeDB::GetTypeField (
687 IN INT8 *FName,
688 IN SVfrDataType *Type,
689 OUT SVfrDataField *&Field
690 )
691 {
692 SVfrDataField *pField = NULL;
693
694 if ((FName == NULL) && (Type == NULL)) {
695 return VFR_RETURN_FATAL_ERROR;
696 }
697
698 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
699 if (strcmp (pField->mFieldName, FName) == 0) {
700 Field = pField;
701 return VFR_RETURN_SUCCESS;
702 }
703 }
704
705 return VFR_RETURN_UNDEFINED;
706 }
707
708 EFI_VFR_RETURN_CODE
709 CVfrVarDataTypeDB::GetFieldOffset (
710 IN SVfrDataField *Field,
711 IN UINT32 ArrayIdx,
712 OUT UINT32 &Offset
713 )
714 {
715 if (Field == NULL) {
716 return VFR_RETURN_FATAL_ERROR;
717 }
718
719 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
720 return VFR_RETURN_ERROR_ARRARY_NUM;
721 }
722
723 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
724 return VFR_RETURN_SUCCESS;
725 }
726
727 UINT8
728 CVfrVarDataTypeDB::GetFieldWidth (
729 IN SVfrDataField *Field
730 )
731 {
732 if (Field == NULL) {
733 return 0;
734 }
735
736 return Field->mFieldType->mType;
737 }
738
739 UINT32
740 CVfrVarDataTypeDB::GetFieldSize (
741 IN SVfrDataField *Field,
742 IN UINT32 ArrayIdx
743 )
744 {
745 if (Field == NULL) {
746 return VFR_RETURN_FATAL_ERROR;
747 }
748
749 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
750 return Field->mFieldType->mTotalSize * Field->mArrayNum;
751 } else {
752 return Field->mFieldType->mTotalSize;
753 }
754 }
755
756 VOID
757 CVfrVarDataTypeDB::InternalTypesListInit (
758 VOID
759 )
760 {
761 SVfrDataType *New = NULL;
762 UINT32 Index;
763
764 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
765 New = new SVfrDataType;
766 if (New != NULL) {
767 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
768 New->mType = gInternalTypesTable[Index].mType;
769 New->mAlign = gInternalTypesTable[Index].mAlign;
770 New->mTotalSize = gInternalTypesTable[Index].mSize;
771 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
772 SVfrDataField *pYearField = new SVfrDataField;
773 SVfrDataField *pMonthField = new SVfrDataField;
774 SVfrDataField *pDayField = new SVfrDataField;
775
776 strcpy (pYearField->mFieldName, "Year");
777 GetDataType ("UINT8", &pYearField->mFieldType);
778 pYearField->mOffset = 0;
779 pYearField->mNext = pMonthField;
780 pYearField->mArrayNum = 0;
781
782 strcpy (pMonthField->mFieldName, "Month");
783 GetDataType ("UINT8", &pMonthField->mFieldType);
784 pMonthField->mOffset = 1;
785 pMonthField->mNext = pDayField;
786 pMonthField->mArrayNum = 0;
787
788 strcpy (pDayField->mFieldName, "Day");
789 GetDataType ("UINT8", &pDayField->mFieldType);
790 pDayField->mOffset = 2;
791 pDayField->mNext = NULL;
792 pDayField->mArrayNum = 0;
793
794 New->mMembers = pYearField;
795 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
796 SVfrDataField *pHoursField = new SVfrDataField;
797 SVfrDataField *pMinutesField = new SVfrDataField;
798 SVfrDataField *pSecondsField = new SVfrDataField;
799
800 strcpy (pHoursField->mFieldName, "Hours");
801 GetDataType ("UINT8", &pHoursField->mFieldType);
802 pHoursField->mOffset = 0;
803 pHoursField->mNext = pMinutesField;
804 pHoursField->mArrayNum = 0;
805
806 strcpy (pMinutesField->mFieldName, "Minutes");
807 GetDataType ("UINT8", &pMinutesField->mFieldType);
808 pMinutesField->mOffset = 1;
809 pMinutesField->mNext = pSecondsField;
810 pMinutesField->mArrayNum = 0;
811
812 strcpy (pSecondsField->mFieldName, "Seconds");
813 GetDataType ("UINT8", &pSecondsField->mFieldType);
814 pSecondsField->mOffset = 2;
815 pSecondsField->mNext = NULL;
816 pSecondsField->mArrayNum = 0;
817
818 New->mMembers = pHoursField;
819 } else {
820 New->mMembers = NULL;
821 }
822 New->mNext = NULL;
823 RegisterNewType (New);
824 New = NULL;
825 }
826 }
827 }
828
829 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
830 VOID
831 )
832 {
833 mDataTypeList = NULL;
834 mNewDataType = NULL;
835 mCurrDataField = NULL;
836 mPackAlign = DEFAULT_PACK_ALIGN;
837
838 InternalTypesListInit ();
839 }
840
841 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
842 VOID
843 )
844 {
845 SVfrDataType *pType;
846 SVfrDataField *pField;
847
848 if (mNewDataType != NULL) {
849 delete mNewDataType;
850 }
851
852 while (mDataTypeList != NULL) {
853 pType = mDataTypeList;
854 mDataTypeList = mDataTypeList->mNext;
855 while(pType->mMembers != NULL) {
856 pField = pType->mMembers;
857 pType->mMembers = pType->mMembers->mNext;
858 delete pField;
859 }
860 delete pType;
861 }
862
863 }
864
865 EFI_VFR_RETURN_CODE
866 CVfrVarDataTypeDB::Pack (
867 IN UINT32 Align
868 )
869 {
870 if (Align == 0) {
871 return VFR_RETURN_INVALID_PARAMETER;
872 } else if (Align > 1) {
873 mPackAlign = Align + Align % 2;
874 } else {
875 mPackAlign = Align;
876 }
877
878 return VFR_RETURN_SUCCESS;
879 }
880
881 VOID
882 CVfrVarDataTypeDB::UnPack (
883 VOID
884 )
885 {
886 mPackAlign = DEFAULT_PACK_ALIGN;
887 }
888
889 VOID
890 CVfrVarDataTypeDB::DeclareDataTypeBegin (
891 VOID
892 )
893 {
894 SVfrDataType *pNewType = NULL;
895
896 pNewType = new SVfrDataType;
897 pNewType->mTypeName[0] = '\0';
898 pNewType->mType = EFI_IFR_TYPE_OTHER;
899 pNewType->mAlign = DEFAULT_ALIGN;
900 pNewType->mTotalSize = 0;
901 pNewType->mMembers = NULL;
902 pNewType->mNext = NULL;
903
904 mNewDataType = pNewType;
905 }
906
907 EFI_VFR_RETURN_CODE
908 CVfrVarDataTypeDB::SetNewTypeName (
909 IN INT8 *TypeName
910 )
911 {
912 SVfrDataType *pType;
913
914 if (mNewDataType == NULL) {
915 return VFR_RETURN_ERROR_SKIPED;
916 }
917 if (TypeName == NULL) {
918 return VFR_RETURN_FATAL_ERROR;
919 }
920 if (strlen(TypeName) >= MAX_NAME_LEN) {
921 return VFR_RETURN_INVALID_PARAMETER;
922 }
923
924 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
925 if (strcmp(pType->mTypeName, TypeName) == 0) {
926 return VFR_RETURN_REDEFINED;
927 }
928 }
929
930 strcpy(mNewDataType->mTypeName, TypeName);
931 return VFR_RETURN_SUCCESS;
932 }
933
934 EFI_VFR_RETURN_CODE
935 CVfrVarDataTypeDB::DataTypeAddField (
936 IN INT8 *FieldName,
937 IN INT8 *TypeName,
938 IN UINT32 ArrayNum
939 )
940 {
941 SVfrDataField *pNewField = NULL;
942 SVfrDataType *pFieldType = NULL;
943 SVfrDataField *pTmp;
944 UINT32 Align;
945
946 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
947
948 if (strlen (FieldName) >= MAX_NAME_LEN) {
949 return VFR_RETURN_INVALID_PARAMETER;
950 }
951
952 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
953 if (strcmp (pTmp->mFieldName, FieldName) == 0) {
954 return VFR_RETURN_REDEFINED;
955 }
956 }
957
958 Align = MIN (mPackAlign, pFieldType->mAlign);
959
960 if ((pNewField = new SVfrDataField) == NULL) {
961 return VFR_RETURN_OUT_FOR_RESOURCES;
962 }
963 strcpy (pNewField->mFieldName, FieldName);
964 pNewField->mFieldType = pFieldType;
965 pNewField->mArrayNum = ArrayNum;
966 if ((mNewDataType->mTotalSize % Align) == 0) {
967 pNewField->mOffset = mNewDataType->mTotalSize;
968 } else {
969 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
970 }
971 if (mNewDataType->mMembers == NULL) {
972 mNewDataType->mMembers = pNewField;
973 pNewField->mNext = NULL;
974 } else {
975 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
976 ;
977 pTmp->mNext = pNewField;
978 pNewField->mNext = NULL;
979 }
980
981 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
982 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
983
984 return VFR_RETURN_SUCCESS;
985 }
986
987 VOID
988 CVfrVarDataTypeDB::DeclareDataTypeEnd (
989 VOID
990 )
991 {
992 if (mNewDataType->mTypeName[0] == '\0') {
993 return;
994 }
995
996 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
997 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
998 }
999
1000 RegisterNewType (mNewDataType);
1001 mNewDataType = NULL;
1002 }
1003
1004 EFI_VFR_RETURN_CODE
1005 CVfrVarDataTypeDB::GetDataType (
1006 IN INT8 *TypeName,
1007 OUT SVfrDataType **DataType
1008
1009 )
1010 {
1011 SVfrDataType *pDataType = NULL;
1012
1013 if (TypeName == NULL) {
1014 return VFR_RETURN_ERROR_SKIPED;
1015 }
1016
1017 if (DataType == NULL) {
1018 return VFR_RETURN_FATAL_ERROR;
1019 }
1020
1021 *DataType = NULL;
1022
1023 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1024 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1025 *DataType = pDataType;
1026 return VFR_RETURN_SUCCESS;
1027 }
1028 }
1029
1030 return VFR_RETURN_UNDEFINED;
1031 }
1032
1033 EFI_VFR_RETURN_CODE
1034 CVfrVarDataTypeDB::GetDataTypeSize (
1035 IN INT8 *TypeName,
1036 OUT UINT32 *Size
1037 )
1038 {
1039 SVfrDataType *pDataType = NULL;
1040
1041 if (Size == NULL) {
1042 return VFR_RETURN_FATAL_ERROR;
1043 }
1044
1045 *Size = 0;
1046
1047 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1048 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1049 *Size = pDataType->mTotalSize;
1050 return VFR_RETURN_SUCCESS;
1051 }
1052 }
1053
1054 return VFR_RETURN_UNDEFINED;
1055 }
1056
1057 EFI_VFR_RETURN_CODE
1058 CVfrVarDataTypeDB::GetDataFieldInfo (
1059 IN INT8 *VarStr,
1060 OUT UINT16 &Offset,
1061 OUT UINT8 &Type,
1062 OUT UINT32 &Size
1063 )
1064 {
1065 INT8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
1066 UINT32 ArrayIdx, Tmp;
1067 SVfrDataType *pType = NULL;
1068 SVfrDataField *pField = NULL;
1069
1070 Offset = 0;
1071 Type = EFI_IFR_TYPE_OTHER;
1072 Size = 0;
1073
1074 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
1075 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
1076
1077 //
1078 // if it is not struct data type
1079 //
1080 Type = pType->mType;
1081 Size = pType->mTotalSize;
1082
1083 while (*VarStr != '\0') {
1084 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
1085 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
1086 pType = pField->mFieldType;
1087 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
1088 Offset += Tmp;
1089 Type = GetFieldWidth (pField);
1090 Size = GetFieldSize (pField, ArrayIdx);
1091 }
1092 return VFR_RETURN_SUCCESS;
1093 }
1094
1095 EFI_VFR_RETURN_CODE
1096 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1097 OUT INT8 ***NameList,
1098 OUT UINT32 *ListSize
1099 )
1100 {
1101 UINT32 Index;
1102 SVfrDataType *pType;
1103
1104 if ((NameList == NULL) || (ListSize == NULL)) {
1105 return VFR_RETURN_FATAL_ERROR;
1106 }
1107
1108 *NameList = NULL;
1109 *ListSize = 0;
1110
1111 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1112 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1113 (*ListSize)++;
1114 }
1115 }
1116
1117 if (*ListSize == 0) {
1118 return VFR_RETURN_SUCCESS;
1119 }
1120
1121 if ((*NameList = new INT8*[*ListSize]) == NULL) {
1122 *ListSize = 0;
1123 return VFR_RETURN_OUT_FOR_RESOURCES;
1124 }
1125
1126 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
1127 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1128 (*NameList)[Index] = pType->mTypeName;
1129 }
1130 }
1131 return VFR_RETURN_SUCCESS;
1132 }
1133
1134 BOOLEAN
1135 CVfrVarDataTypeDB::IsTypeNameDefined (
1136 IN INT8 *TypeName
1137 )
1138 {
1139 SVfrDataType *pType;
1140
1141 if (TypeName == NULL) {
1142 return FALSE;
1143 }
1144
1145 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1146 if (strcmp (pType->mTypeName, TypeName) == 0) {
1147 return TRUE;
1148 }
1149 }
1150
1151 return FALSE;
1152 }
1153
1154 #ifdef CVFR_VARDATATYPEDB_DEBUG
1155 VOID
1156 CVfrVarDataTypeDB::ParserDB (
1157 VOID
1158 )
1159 {
1160 SVfrDataType *pTNode;
1161 SVfrDataField *pFNode;
1162
1163 printf ("***************************************************************\n");
1164 printf ("\t\tmPackAlign = %x\n", mPackAlign);
1165 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1166 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1167 printf ("\t\tstruct %s {\n", pTNode->mTypeName);
1168 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1169 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
1170 }
1171 printf ("\t\t};\n");
1172 printf ("---------------------------------------------------------------\n");
1173 }
1174 printf ("***************************************************************\n");
1175 }
1176 #endif
1177
1178 SVfrVarStorageNode::SVfrVarStorageNode (
1179 IN EFI_GUID *Guid,
1180 IN INT8 *StoreName,
1181 IN EFI_VARSTORE_ID VarStoreId,
1182 IN EFI_STRING_ID VarName,
1183 IN UINT32 VarSize
1184 )
1185 {
1186 if (Guid != NULL) {
1187 mGuid = *Guid;
1188 } else {
1189 memset (&Guid, 0, sizeof (EFI_GUID));
1190 }
1191 if (StoreName != NULL) {
1192 mVarStoreName = new INT8[strlen(StoreName) + 1];
1193 strcpy (mVarStoreName, StoreName);
1194 } else {
1195 mVarStoreName = NULL;
1196 }
1197 mNext = NULL;
1198 mVarStoreId = VarStoreId;
1199 mVarStoreType = EFI_VFR_VARSTORE_EFI;
1200 mStorageInfo.mEfiVar.mEfiVarName = VarName;
1201 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
1202 }
1203
1204 SVfrVarStorageNode::SVfrVarStorageNode (
1205 IN EFI_GUID *Guid,
1206 IN INT8 *StoreName,
1207 IN EFI_VARSTORE_ID VarStoreId,
1208 IN SVfrDataType *DataType
1209 )
1210 {
1211 if (Guid != NULL) {
1212 mGuid = *Guid;
1213 } else {
1214 memset (&Guid, 0, sizeof (EFI_GUID));
1215 }
1216 if (StoreName != NULL) {
1217 mVarStoreName = new INT8[strlen(StoreName) + 1];
1218 strcpy (mVarStoreName, StoreName);
1219 } else {
1220 mVarStoreName = NULL;
1221 }
1222 mNext = NULL;
1223 mVarStoreId = VarStoreId;
1224 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
1225 mStorageInfo.mDataType = DataType;
1226 }
1227
1228 SVfrVarStorageNode::SVfrVarStorageNode (
1229 IN INT8 *StoreName,
1230 IN EFI_VARSTORE_ID VarStoreId
1231 )
1232 {
1233 if (StoreName != NULL) {
1234 mVarStoreName = new INT8[strlen(StoreName) + 1];
1235 strcpy (mVarStoreName, StoreName);
1236 } else {
1237 mVarStoreName = NULL;
1238 }
1239 mNext = NULL;
1240 mVarStoreId = VarStoreId;
1241 mVarStoreType = EFI_VFR_VARSTORE_NAME;
1242 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
1243 mStorageInfo.mNameSpace.mTableSize = 0;
1244 }
1245
1246 SVfrVarStorageNode::~SVfrVarStorageNode (
1247 VOID
1248 )
1249 {
1250 if (mVarStoreName != NULL) {
1251 delete mVarStoreName;
1252 }
1253
1254 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
1255 delete mStorageInfo.mNameSpace.mNameTable;
1256 }
1257 }
1258
1259 CVfrDataStorage::CVfrDataStorage (
1260 VOID
1261 )
1262 {
1263 UINT32 Index;
1264
1265 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1266 mFreeVarStoreIdBitMap[Index] = 0;
1267 }
1268
1269 // Question ID 0 is reserved.
1270 mFreeVarStoreIdBitMap[0] = 0x80000000;
1271
1272 mBufferVarStoreList = NULL;
1273 mEfiVarStoreList = NULL;
1274 mNameVarStoreList = NULL;
1275 mCurrVarStorageNode = NULL;
1276 mNewVarStorageNode = NULL;
1277 }
1278
1279 CVfrDataStorage::~CVfrDataStorage (
1280 VOID
1281 )
1282 {
1283 SVfrVarStorageNode *pNode;
1284
1285 while (mBufferVarStoreList != NULL) {
1286 pNode = mBufferVarStoreList;
1287 mBufferVarStoreList = mBufferVarStoreList->mNext;
1288 delete pNode;
1289 }
1290 while (mEfiVarStoreList != NULL) {
1291 pNode = mEfiVarStoreList;
1292 mEfiVarStoreList = mEfiVarStoreList->mNext;
1293 delete pNode;
1294 }
1295 while (mNameVarStoreList != NULL) {
1296 pNode = mNameVarStoreList;
1297 mNameVarStoreList = mNameVarStoreList->mNext;
1298 delete pNode;
1299 }
1300 if (mNewVarStorageNode != NULL) {
1301 delete mNewVarStorageNode;
1302 }
1303 }
1304
1305 EFI_VARSTORE_ID
1306 CVfrDataStorage::GetFreeVarStoreId (
1307 VOID
1308 )
1309 {
1310 UINT32 Index, Mask, Offset;
1311
1312 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1313 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1314 break;
1315 }
1316 }
1317
1318 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1319 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1320 mFreeVarStoreIdBitMap[Index] |= Mask;
1321 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1322 }
1323 }
1324
1325 return EFI_VARSTORE_ID_INVALID;
1326 }
1327
1328 BOOLEAN
1329 CVfrDataStorage::ChekVarStoreIdFree (
1330 IN EFI_VARSTORE_ID VarStoreId
1331 )
1332 {
1333 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1334 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1335
1336 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1337 }
1338
1339 VOID
1340 CVfrDataStorage::MarkVarStoreIdUsed (
1341 IN EFI_VARSTORE_ID VarStoreId
1342 )
1343 {
1344 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1345 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1346
1347 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1348 }
1349
1350 VOID
1351 CVfrDataStorage::MarkVarStoreIdUnused (
1352 IN EFI_VARSTORE_ID VarStoreId
1353 )
1354 {
1355 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1356 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1357
1358 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1359 }
1360
1361 EFI_VFR_RETURN_CODE
1362 CVfrDataStorage::DeclareNameVarStoreBegin (
1363 IN INT8 *StoreName
1364 )
1365 {
1366 SVfrVarStorageNode *pNode = NULL;
1367 EFI_VARSTORE_ID VarStoreId;
1368
1369 if (StoreName == NULL) {
1370 return VFR_RETURN_FATAL_ERROR;
1371 }
1372
1373 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1374 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1375 return VFR_RETURN_REDEFINED;
1376 }
1377 }
1378
1379 VarStoreId = GetFreeVarStoreId ();
1380 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1381 return VFR_RETURN_UNDEFINED;
1382 }
1383
1384 mNewVarStorageNode = pNode;
1385
1386 return VFR_RETURN_SUCCESS;
1387 }
1388
1389 EFI_VFR_RETURN_CODE
1390 CVfrDataStorage::NameTableAddItem (
1391 IN EFI_STRING_ID Item
1392 )
1393 {
1394 EFI_VARSTORE_ID *NewTable, *OldTable;
1395 UINT32 TableSize;
1396
1397 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1398 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1399
1400 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1401 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1402 return VFR_RETURN_OUT_FOR_RESOURCES;
1403 }
1404 memcpy (NewTable, OldTable, TableSize);
1405 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1406 }
1407
1408 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1409 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1410
1411 return VFR_RETURN_SUCCESS;
1412 }
1413
1414 EFI_VFR_RETURN_CODE
1415 CVfrDataStorage::DeclareNameVarStoreEnd (
1416 IN EFI_GUID *Guid
1417 )
1418 {
1419 mNewVarStorageNode->mGuid = *Guid;
1420 mNewVarStorageNode->mNext = mNameVarStoreList;
1421 mNameVarStoreList = mNewVarStorageNode;
1422
1423 mNewVarStorageNode = NULL;
1424
1425 return VFR_RETURN_SUCCESS;
1426 }
1427
1428 EFI_VFR_RETURN_CODE
1429 CVfrDataStorage::DeclareEfiVarStore (
1430 IN INT8 *StoreName,
1431 IN EFI_GUID *Guid,
1432 IN EFI_STRING_ID NameStrId,
1433 IN UINT32 VarSize
1434 )
1435 {
1436 SVfrVarStorageNode *pNode;
1437 EFI_VARSTORE_ID VarStoreId;
1438
1439 if ((StoreName == NULL) || (Guid == NULL)) {
1440 return VFR_RETURN_FATAL_ERROR;
1441 }
1442
1443 if (VarSize > sizeof (UINT64)) {
1444 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1445 }
1446
1447 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1448 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1449 return VFR_RETURN_REDEFINED;
1450 }
1451 }
1452
1453 VarStoreId = GetFreeVarStoreId ();
1454 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize)) == NULL) {
1455 return VFR_RETURN_OUT_FOR_RESOURCES;
1456 }
1457
1458 pNode->mNext = mNameVarStoreList;
1459 mNameVarStoreList = pNode;
1460
1461 return VFR_RETURN_SUCCESS;
1462 }
1463
1464 EFI_VFR_RETURN_CODE
1465 CVfrDataStorage::DeclareBufferVarStore (
1466 IN INT8 *StoreName,
1467 IN EFI_GUID *Guid,
1468 IN CVfrVarDataTypeDB *DataTypeDB,
1469 IN INT8 *TypeName,
1470 IN EFI_VARSTORE_ID VarStoreId
1471 )
1472 {
1473 SVfrVarStorageNode *pNew = NULL;
1474 SVfrDataType *pDataType = NULL;
1475
1476 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1477 return VFR_RETURN_FATAL_ERROR;
1478 }
1479
1480 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1481
1482 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1483 VarStoreId = GetFreeVarStoreId ();
1484 } else {
1485 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1486 return VFR_RETURN_VARSTOREID_REDEFINED;
1487 }
1488 MarkVarStoreIdUsed (VarStoreId);
1489 }
1490
1491 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType)) == NULL) {
1492 return VFR_RETURN_OUT_FOR_RESOURCES;
1493 }
1494
1495 pNew->mNext = mBufferVarStoreList;
1496 mBufferVarStoreList = pNew;
1497
1498 if (gCVfrBufferConfig.Register(StoreName) != 0) {
1499 return VFR_RETURN_FATAL_ERROR;
1500 }
1501
1502 return VFR_RETURN_SUCCESS;
1503 }
1504
1505 EFI_VFR_RETURN_CODE
1506 CVfrDataStorage::GetVarStoreId (
1507 IN INT8 *StoreName,
1508 OUT EFI_VARSTORE_ID *VarStoreId
1509 )
1510 {
1511 SVfrVarStorageNode *pNode;
1512
1513 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1514 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1515 mCurrVarStorageNode = pNode;
1516 *VarStoreId = pNode->mVarStoreId;
1517 return VFR_RETURN_SUCCESS;
1518 }
1519 }
1520
1521 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1522 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1523 mCurrVarStorageNode = pNode;
1524 *VarStoreId = pNode->mVarStoreId;
1525 return VFR_RETURN_SUCCESS;
1526 }
1527 }
1528
1529 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1530 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1531 mCurrVarStorageNode = pNode;
1532 *VarStoreId = pNode->mVarStoreId;
1533 return VFR_RETURN_SUCCESS;
1534 }
1535 }
1536
1537 mCurrVarStorageNode = NULL;
1538 *VarStoreId = EFI_VARSTORE_ID_INVALID;
1539 return VFR_RETURN_UNDEFINED;
1540 }
1541
1542 EFI_VFR_RETURN_CODE
1543 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1544 IN INT8 *StoreName,
1545 OUT INT8 **DataTypeName
1546 )
1547 {
1548 SVfrVarStorageNode *pNode;
1549
1550 if ((StoreName == NULL) || (DataTypeName == NULL)) {
1551 return VFR_RETURN_FATAL_ERROR;
1552 }
1553
1554 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1555 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1556 break;
1557 }
1558 }
1559
1560 if (pNode == NULL) {
1561 return VFR_RETURN_UNDEFINED;
1562 }
1563
1564 if (pNode->mStorageInfo.mDataType == NULL) {
1565 return VFR_RETURN_FATAL_ERROR;
1566 }
1567
1568 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
1569 return VFR_RETURN_SUCCESS;
1570 }
1571
1572 EFI_VFR_RETURN_CODE
1573 CVfrDataStorage::GetVarStoreType (
1574 IN INT8 *StoreName,
1575 OUT EFI_VFR_VARSTORE_TYPE &VarStoreType
1576 )
1577 {
1578 SVfrVarStorageNode *pNode;
1579
1580 if (StoreName == NULL) {
1581 return VFR_RETURN_FATAL_ERROR;
1582 }
1583
1584 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1585 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
1586 VarStoreType = pNode->mVarStoreType;
1587 return VFR_RETURN_SUCCESS;
1588 }
1589 }
1590
1591 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1592 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
1593 VarStoreType = pNode->mVarStoreType;
1594 return VFR_RETURN_SUCCESS;
1595 }
1596 }
1597
1598 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1599 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
1600 VarStoreType = pNode->mVarStoreType;
1601 return VFR_RETURN_SUCCESS;
1602 }
1603 }
1604
1605 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1606 return VFR_RETURN_UNDEFINED;
1607 }
1608
1609 EFI_VFR_RETURN_CODE
1610 CVfrDataStorage::GetVarStoreName (
1611 IN EFI_VARSTORE_ID VarStoreId,
1612 OUT INT8 **VarStoreName
1613 )
1614 {
1615 SVfrVarStorageNode *pNode;
1616
1617 if (VarStoreName == NULL) {
1618 return VFR_RETURN_FATAL_ERROR;
1619 }
1620
1621 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1622 if (pNode->mVarStoreId == VarStoreId) {
1623 *VarStoreName = pNode->mVarStoreName;
1624 return VFR_RETURN_SUCCESS;
1625 }
1626 }
1627
1628 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1629 if (pNode->mVarStoreId == VarStoreId) {
1630 *VarStoreName = pNode->mVarStoreName;
1631 return VFR_RETURN_SUCCESS;
1632 }
1633 }
1634
1635 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1636 if (pNode->mVarStoreId == VarStoreId) {
1637 *VarStoreName = pNode->mVarStoreName;
1638 return VFR_RETURN_SUCCESS;
1639 }
1640 }
1641
1642 *VarStoreName = NULL;
1643 return VFR_RETURN_UNDEFINED;
1644 }
1645
1646 EFI_VFR_RETURN_CODE
1647 CVfrDataStorage::GetEfiVarStoreInfo (
1648 IN OUT EFI_VARSTORE_INFO *Info
1649 )
1650 {
1651 if (Info == NULL) {
1652 return VFR_RETURN_FATAL_ERROR;
1653 }
1654
1655 if (mCurrVarStorageNode == NULL) {
1656 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
1657 }
1658
1659 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
1660 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
1661 switch (Info->mVarTotalSize) {
1662 case 1:
1663 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
1664 break;
1665 case 2:
1666 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
1667 break;
1668 case 4:
1669 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
1670 break;
1671 case 8:
1672 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
1673 break;
1674 default :
1675 return VFR_RETURN_FATAL_ERROR;
1676 }
1677
1678 return VFR_RETURN_SUCCESS;
1679 }
1680
1681 EFI_VFR_RETURN_CODE
1682 CVfrDataStorage::GetNameVarStoreInfo (
1683 OUT EFI_VARSTORE_INFO *Info,
1684 IN UINT32 Index
1685 )
1686 {
1687 if (Info == NULL) {
1688 return VFR_RETURN_FATAL_ERROR;
1689 }
1690
1691 if (mCurrVarStorageNode == NULL) {
1692 return VFR_RETURN_GET_NVVARSTORE_ERROR;
1693 }
1694
1695 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
1696
1697 return VFR_RETURN_SUCCESS;
1698 }
1699
1700 EFI_VFR_RETURN_CODE
1701 CVfrDataStorage::BufferVarStoreRequestElementAdd (
1702 IN INT8 *StoreName,
1703 IN EFI_VARSTORE_INFO &Info
1704 )
1705 {
1706 INT8 NewReqElt[128] = {'\0',};
1707 INT8 *OldReqElt = NULL;
1708 SVfrVarStorageNode *pNode = NULL;
1709 EFI_IFR_TYPE_VALUE Value;
1710
1711 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1712 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
1713 break;
1714 }
1715 }
1716
1717 if (pNode == NULL) {
1718 return VFR_RETURN_UNDEFINED;
1719 }
1720
1721 gCVfrBufferConfig.Open ();
1722 Value.u8 = 0;
1723 if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
1724 return VFR_RETURN_FATAL_ERROR;
1725 }
1726 gCVfrBufferConfig.Close ();
1727
1728 return VFR_RETURN_SUCCESS;
1729 }
1730
1731 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
1732 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
1733 IN INT8 *RefName,
1734 IN EFI_STRING_ID DefaultStoreNameId,
1735 IN UINT16 DefaultId
1736 )
1737 {
1738 mObjBinAddr = ObjBinAddr;
1739
1740 if (RefName != NULL) {
1741 mRefName = new INT8[strlen (RefName) + 1];
1742 strcpy (mRefName, RefName);
1743 } else {
1744 mRefName = NULL;
1745 }
1746
1747 mNext = NULL;
1748 mDefaultId = DefaultId;
1749 mDefaultStoreNameId = DefaultStoreNameId;
1750 }
1751
1752 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
1753 VOID
1754 )
1755 {
1756 if (mRefName != NULL) {
1757 delete mRefName;
1758 }
1759 }
1760
1761 CVfrDefaultStore::CVfrDefaultStore (
1762 VOID
1763 )
1764 {
1765 mDefaultStoreList = NULL;
1766 }
1767
1768 CVfrDefaultStore::~CVfrDefaultStore (
1769 VOID
1770 )
1771 {
1772 SVfrDefaultStoreNode *pTmp = NULL;
1773
1774 while (mDefaultStoreList != NULL) {
1775 pTmp = mDefaultStoreList;
1776 mDefaultStoreList = mDefaultStoreList->mNext;
1777 delete pTmp;
1778 }
1779 }
1780
1781 EFI_VFR_RETURN_CODE
1782 CVfrDefaultStore::RegisterDefaultStore (
1783 IN CHAR8 *ObjBinAddr,
1784 IN INT8 *RefName,
1785 IN EFI_STRING_ID DefaultStoreNameId,
1786 IN UINT16 DefaultId
1787 )
1788 {
1789 SVfrDefaultStoreNode *pNode = NULL;
1790
1791 if (RefName == NULL) {
1792 return VFR_RETURN_FATAL_ERROR;
1793 }
1794
1795 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1796 if (strcmp (pNode->mRefName, RefName) == 0) {
1797 return VFR_RETURN_REDEFINED;
1798 }
1799 }
1800
1801 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
1802 return VFR_RETURN_OUT_FOR_RESOURCES;
1803 }
1804
1805 pNode->mNext = mDefaultStoreList;
1806 mDefaultStoreList = pNode;
1807
1808 return VFR_RETURN_SUCCESS;
1809 }
1810
1811 /*
1812 * assign new reference name or new default store name id only if
1813 * the original is invalid
1814 */
1815 EFI_VFR_RETURN_CODE
1816 CVfrDefaultStore::ReRegisterDefaultStoreById (
1817 IN UINT16 DefaultId,
1818 IN INT8 *RefName,
1819 IN EFI_STRING_ID DefaultStoreNameId
1820 )
1821 {
1822 SVfrDefaultStoreNode *pNode = NULL;
1823
1824 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1825 if (pNode->mDefaultId == DefaultId) {
1826 break;
1827 }
1828 }
1829
1830 if (pNode == NULL) {
1831 return VFR_RETURN_UNDEFINED;
1832 } else {
1833 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
1834 pNode->mDefaultStoreNameId = DefaultStoreNameId;
1835 if (pNode->mObjBinAddr != NULL) {
1836 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
1837 }
1838 } else {
1839 return VFR_RETURN_REDEFINED;
1840 }
1841
1842 if (RefName != NULL) {
1843 delete pNode->mRefName;
1844 pNode->mRefName = new INT8[strlen (RefName) + 1];
1845 if (pNode->mRefName != NULL) {
1846 strcpy (pNode->mRefName, RefName);
1847 }
1848 }
1849 }
1850
1851 return VFR_RETURN_SUCCESS;
1852 }
1853
1854 BOOLEAN
1855 CVfrDefaultStore::DefaultIdRegistered (
1856 IN UINT16 DefaultId
1857 )
1858 {
1859 SVfrDefaultStoreNode *pNode = NULL;
1860
1861 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1862 if (pNode->mDefaultId == DefaultId) {
1863 return TRUE;
1864 }
1865 }
1866
1867 return FALSE;
1868 }
1869
1870 EFI_VFR_RETURN_CODE
1871 CVfrDefaultStore::GetDefaultId (
1872 IN INT8 *RefName,
1873 OUT UINT16 *DefaultId
1874 )
1875 {
1876 SVfrDefaultStoreNode *pTmp = NULL;
1877
1878 if (DefaultId == NULL) {
1879 return VFR_RETURN_FATAL_ERROR;
1880 }
1881
1882 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
1883 if (strcmp (pTmp->mRefName, RefName) == 0) {
1884 *DefaultId = pTmp->mDefaultId;
1885 return VFR_RETURN_SUCCESS;
1886 }
1887 }
1888
1889 return VFR_RETURN_UNDEFINED;
1890 }
1891
1892 STATIC
1893 EFI_VFR_RETURN_CODE
1894 AltCfgItemPrintToBuffer (
1895 IN INT8 *NewAltCfg,
1896 IN EFI_VARSTORE_INFO Info,
1897 IN UINT8 Type,
1898 IN EFI_IFR_TYPE_VALUE Value
1899 )
1900 {
1901 UINT32 Index;
1902 UINT8 *BufChar = NULL;
1903 UINT32 Count = 0;
1904
1905 if (NewAltCfg != NULL) {
1906 Count = sprintf (
1907 NewAltCfg,
1908 "&OFFSET=%x&WIDTH=%x&VALUE=",
1909 Info.mInfo.mVarOffset,
1910 Info.mVarTotalSize
1911 );
1912 NewAltCfg += Count;
1913
1914 switch (Type) {
1915 case EFI_IFR_TYPE_NUM_SIZE_8 :
1916 Count = sprintf (NewAltCfg, "%x", Value.u8);
1917 NewAltCfg += Count;
1918 break;
1919 case EFI_IFR_TYPE_NUM_SIZE_16 :
1920 Count = sprintf (NewAltCfg, "%x", Value.u16);
1921 NewAltCfg += Count;
1922 break;
1923 case EFI_IFR_TYPE_NUM_SIZE_32 :
1924 Count = sprintf (NewAltCfg, "%x", Value.u32);
1925 NewAltCfg += Count;
1926 break;
1927 case EFI_IFR_TYPE_NUM_SIZE_64 :
1928 Count = sprintf (NewAltCfg, "%x", Value.u64);
1929 NewAltCfg += Count;
1930 break;
1931 case EFI_IFR_TYPE_BOOLEAN :
1932 Count = sprintf (NewAltCfg, "%x", Value.b);
1933 NewAltCfg += Count;
1934 break;
1935 case EFI_IFR_TYPE_TIME :
1936 #if 1
1937 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));
1938 NewAltCfg += Count;
1939 #else
1940 BufChar = (UINT8 *)&Value.time;
1941 for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {
1942 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
1943 NewAltCfg += Count;
1944 }
1945 #endif
1946 break;
1947 case EFI_IFR_TYPE_DATE :
1948 #if 1
1949 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));
1950 NewAltCfg += Count;
1951 #else
1952 BufChar = (UINT8 *)&Value.date;
1953 for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {
1954 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
1955 NewAltCfg += Count;
1956 }
1957 #endif
1958 break;
1959 case EFI_IFR_TYPE_STRING :
1960 Count = sprintf (NewAltCfg, "%x", Value.string);
1961 NewAltCfg += Count;
1962 break;
1963 case EFI_IFR_TYPE_OTHER :
1964 return VFR_RETURN_UNSUPPORTED;
1965 }
1966 }
1967
1968 return VFR_RETURN_FATAL_ERROR;
1969 }
1970
1971 EFI_VFR_RETURN_CODE
1972 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
1973 IN EFI_VARSTORE_ID DefaultId,
1974 IN EFI_VARSTORE_INFO &Info,
1975 IN INT8 *VarStoreName,
1976 IN UINT8 Type,
1977 IN EFI_IFR_TYPE_VALUE Value
1978 )
1979 {
1980 SVfrDefaultStoreNode *pNode = NULL;
1981 INT8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
1982
1983 if (VarStoreName == NULL) {
1984 return VFR_RETURN_FATAL_ERROR;
1985 }
1986
1987 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1988 if (pNode->mDefaultId == DefaultId) {
1989 break;
1990 }
1991 }
1992
1993 if (pNode == NULL) {
1994 return VFR_RETURN_UNDEFINED;
1995 }
1996
1997 gCVfrBufferConfig.Open ();
1998
1999 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2000 if ((gCVfrBufferConfig.Select(VarStoreName) == 0) &&
2001 (gCVfrBufferConfig.Select(VarStoreName, NewAltCfg) != 0)) {
2002 if (gCVfrBufferConfig.Write ('i', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
2003 goto WriteError;
2004 }
2005 }
2006
2007 if (gCVfrBufferConfig.Write ('a', VarStoreName, NULL, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
2008 goto WriteError;
2009 }
2010
2011 gCVfrBufferConfig.Close ();
2012
2013 return VFR_RETURN_SUCCESS;
2014
2015 WriteError:
2016 gCVfrBufferConfig.Close ();
2017 return VFR_RETURN_FATAL_ERROR;
2018 }
2019
2020 SVfrRuleNode::SVfrRuleNode (
2021 IN INT8 *RuleName,
2022 IN UINT8 RuleId
2023 )
2024 {
2025 if (RuleName != NULL) {
2026 mRuleName = new INT8[strlen (RuleName) + 1];
2027 strcpy (mRuleName, RuleName);
2028 } else {
2029 mRuleName = NULL;
2030 }
2031
2032 mNext = NULL;
2033 mRuleId = RuleId;
2034 }
2035
2036 SVfrRuleNode::~SVfrRuleNode (
2037 VOID
2038 )
2039 {
2040 if (mRuleName != NULL) {
2041 delete mRuleName;
2042 }
2043 }
2044
2045 CVfrRulesDB::CVfrRulesDB ()
2046 {
2047 mRuleList = NULL;
2048 mFreeRuleId = EFI_VARSTORE_ID_START;
2049 }
2050
2051 CVfrRulesDB::~CVfrRulesDB ()
2052 {
2053 SVfrRuleNode *pNode;
2054
2055 while(mRuleList != NULL) {
2056 pNode = mRuleList;
2057 mRuleList = mRuleList->mNext;
2058 delete pNode;
2059 }
2060 }
2061
2062 VOID
2063 CVfrRulesDB::RegisterRule (
2064 IN INT8 *RuleName
2065 )
2066 {
2067 SVfrRuleNode *pNew;
2068
2069 if (RuleName == NULL) {
2070 return ;
2071 }
2072
2073 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2074 return ;
2075 }
2076
2077 mFreeRuleId++;
2078
2079 pNew->mNext = mRuleList;
2080 mRuleList = pNew;
2081 }
2082
2083 UINT8
2084 CVfrRulesDB::GetRuleId (
2085 IN INT8 *RuleName
2086 )
2087 {
2088 SVfrRuleNode *pNode;
2089
2090 if (RuleName == NULL) {
2091 return EFI_RULE_ID_INVALID;
2092 }
2093
2094 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2095 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2096 return pNode->mRuleId;
2097 }
2098 }
2099
2100 return EFI_RULE_ID_INVALID;
2101 }
2102
2103 CVfrRulesDB gCVfrRulesDB;
2104
2105 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2106 VOID
2107 )
2108 {
2109 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2110 mInfo.mVarName = EFI_STRING_ID_INVALID;
2111 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2112 mVarType = EFI_IFR_TYPE_OTHER;
2113 mVarTotalSize = 0;
2114 }
2115
2116 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2117 IN EFI_VARSTORE_INFO &Info
2118 )
2119 {
2120 mVarStoreId = Info.mVarStoreId;
2121 mInfo.mVarName = Info.mInfo.mVarName;
2122 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2123 mVarType = Info.mVarType;
2124 mVarTotalSize = Info.mVarTotalSize;
2125 }
2126
2127 BOOLEAN
2128 EFI_VARSTORE_INFO::operator == (
2129 IN EFI_VARSTORE_INFO *Info
2130 )
2131 {
2132 if ((mVarStoreId == Info->mVarStoreId) &&
2133 (mInfo.mVarName == Info->mInfo.mVarName) &&
2134 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2135 (mVarType == Info->mVarType) &&
2136 (mVarTotalSize == Info->mVarTotalSize)) {
2137 return TRUE;
2138 }
2139
2140 return FALSE;
2141 }
2142
2143 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2144
2145 EFI_QUESTION_ID
2146 CVfrQuestionDB::GetFreeQuestionId (
2147 VOID
2148 )
2149 {
2150 UINT32 Index, Mask, Offset;
2151
2152 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2153 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2154 break;
2155 }
2156 }
2157
2158 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2159 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2160 mFreeQIdBitMap[Index] |= Mask;
2161 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2162 }
2163 }
2164
2165 return EFI_QUESTION_ID_INVALID;
2166 }
2167
2168 BOOLEAN
2169 CVfrQuestionDB::ChekQuestionIdFree (
2170 IN EFI_QUESTION_ID QId
2171 )
2172 {
2173 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2174 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2175
2176 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2177 }
2178
2179 VOID
2180 CVfrQuestionDB::MarkQuestionIdUsed (
2181 IN EFI_QUESTION_ID QId
2182 )
2183 {
2184 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2185 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2186
2187 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2188 }
2189
2190 VOID
2191 CVfrQuestionDB::MarkQuestionIdUnused (
2192 IN EFI_QUESTION_ID QId
2193 )
2194 {
2195 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2196 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2197
2198 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2199 }
2200
2201 SVfrQuestionNode::SVfrQuestionNode (
2202 IN INT8 *Name,
2203 IN INT8 *VarIdStr,
2204 IN UINT32 BitMask
2205 )
2206 {
2207 mName = NULL;
2208 mVarIdStr = NULL;
2209 mQuestionId = EFI_QUESTION_ID_INVALID;
2210 mBitMask = BitMask;
2211 mNext = NULL;
2212
2213 if (Name == NULL) {
2214 mName = new INT8[strlen ("$DEFAULT") + 1];
2215 strcpy (mName, "$DEFAULT");
2216 } else {
2217 mName = new INT8[strlen (Name) + 1];
2218 strcpy (mName, Name);
2219 }
2220
2221 if (VarIdStr != NULL) {
2222 mVarIdStr = new INT8[strlen (VarIdStr) + 1];
2223 strcpy (mVarIdStr, VarIdStr);
2224 } else {
2225 mVarIdStr = new INT8[strlen ("$") + 1];
2226 strcpy (mVarIdStr, "$");
2227 }
2228 }
2229
2230 SVfrQuestionNode::~SVfrQuestionNode (
2231 VOID
2232 )
2233 {
2234 if (mName != NULL) {
2235 delete mName;
2236 }
2237
2238 if (mVarIdStr != NULL) {
2239 delete mVarIdStr;
2240 }
2241 }
2242
2243 CVfrQuestionDB::CVfrQuestionDB ()
2244 {
2245 UINT32 Index;
2246
2247 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2248 mFreeQIdBitMap[Index] = 0;
2249 }
2250
2251 // Question ID 0 is reserved.
2252 mFreeQIdBitMap[0] = 0x80000000;
2253 mQuestionList = NULL;
2254 }
2255
2256 CVfrQuestionDB::~CVfrQuestionDB ()
2257 {
2258 SVfrQuestionNode *pNode;
2259
2260 while (mQuestionList != NULL) {
2261 pNode = mQuestionList;
2262 mQuestionList = mQuestionList->mNext;
2263 delete pNode;
2264 }
2265 }
2266
2267 EFI_VFR_RETURN_CODE
2268 CVfrQuestionDB::RegisterQuestion (
2269 IN INT8 *Name,
2270 IN INT8 *VarIdStr,
2271 IN OUT EFI_QUESTION_ID &QuestionId
2272 )
2273 {
2274 SVfrQuestionNode *pNode = NULL;
2275
2276 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2277 return VFR_RETURN_REDEFINED;
2278 }
2279
2280 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2281 return VFR_RETURN_OUT_FOR_RESOURCES;
2282 }
2283
2284 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2285 QuestionId = GetFreeQuestionId ();
2286 } else {
2287 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2288 delete pNode;
2289 return VFR_RETURN_QUESTIONID_REDEFINED;
2290 }
2291 MarkQuestionIdUsed (QuestionId);
2292 }
2293 pNode->mQuestionId = QuestionId;
2294
2295 pNode->mNext = mQuestionList;
2296 mQuestionList = pNode;
2297
2298 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2299
2300 return VFR_RETURN_SUCCESS;
2301 }
2302
2303 VOID
2304 CVfrQuestionDB::RegisterOldDateQuestion (
2305 IN INT8 *YearVarId,
2306 IN INT8 *MonthVarId,
2307 IN INT8 *DayVarId,
2308 IN OUT EFI_QUESTION_ID &QuestionId
2309 )
2310 {
2311 SVfrQuestionNode *pNode[3] = {NULL, };
2312 UINT32 Index;
2313
2314 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2315 return;
2316 }
2317
2318 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2319 goto Err;
2320 }
2321 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2322 goto Err;
2323 }
2324 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2325 goto Err;
2326 }
2327
2328 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2329 QuestionId = GetFreeQuestionId ();
2330 } else {
2331 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2332 goto Err;
2333 }
2334 MarkQuestionIdUsed (QuestionId);
2335 }
2336
2337 pNode[0]->mQuestionId = QuestionId;
2338 pNode[1]->mQuestionId = QuestionId;
2339 pNode[2]->mQuestionId = QuestionId;
2340 pNode[0]->mNext = pNode[1];
2341 pNode[1]->mNext = pNode[2];
2342 pNode[2]->mNext = mQuestionList;
2343 mQuestionList = pNode[0];
2344
2345 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2346 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2347 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2348
2349 return;
2350
2351 Err:
2352 for (Index = 0; Index < 3; Index++) {
2353 if (pNode[Index] != NULL) {
2354 delete pNode[Index];
2355 }
2356 }
2357 QuestionId = EFI_QUESTION_ID_INVALID;
2358 }
2359
2360 VOID
2361 CVfrQuestionDB::RegisterNewDateQuestion (
2362 IN INT8 *Name,
2363 IN INT8 *BaseVarId,
2364 IN OUT EFI_QUESTION_ID &QuestionId
2365 )
2366 {
2367 SVfrQuestionNode *pNode[3] = {NULL, };
2368 UINT32 Len;
2369 INT8 *VarIdStr[3] = {NULL, };
2370 INT8 Index;
2371
2372 if (BaseVarId == NULL) {
2373 return;
2374 }
2375
2376 Len = strlen (BaseVarId);
2377
2378 VarIdStr[0] = new INT8[Len + strlen (".Year") + 1];
2379 if (VarIdStr[0] != NULL) {
2380 strcpy (VarIdStr[0], BaseVarId);
2381 strcat (VarIdStr[0], ".Year");
2382 }
2383 VarIdStr[1] = new INT8[Len + strlen (".Month") + 1];
2384 if (VarIdStr[1] != NULL) {
2385 strcpy (VarIdStr[1], BaseVarId);
2386 strcat (VarIdStr[1], ".Month");
2387 }
2388 VarIdStr[2] = new INT8[Len + strlen (".Day") + 1];
2389 if (VarIdStr[2] != NULL) {
2390 strcpy (VarIdStr[2], BaseVarId);
2391 strcat (VarIdStr[2], ".Day");
2392 }
2393
2394 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2395 goto Err;
2396 }
2397 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2398 goto Err;
2399 }
2400 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2401 goto Err;
2402 }
2403
2404 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2405 QuestionId = GetFreeQuestionId ();
2406 } else {
2407 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2408 goto Err;
2409 }
2410 MarkQuestionIdUsed (QuestionId);
2411 }
2412
2413 pNode[0]->mQuestionId = QuestionId;
2414 pNode[1]->mQuestionId = QuestionId;
2415 pNode[2]->mQuestionId = QuestionId;
2416 pNode[0]->mNext = pNode[1];
2417 pNode[1]->mNext = pNode[2];
2418 pNode[2]->mNext = mQuestionList;
2419 mQuestionList = pNode[0];
2420
2421 for (Index = 0; Index < 3; Index++) {
2422 if (VarIdStr[Index] != NULL) {
2423 delete VarIdStr[Index];
2424 }
2425 }
2426
2427 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2428 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2429 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2430
2431 return;
2432
2433 Err:
2434 for (Index = 0; Index < 3; Index++) {
2435 if (pNode[Index] != NULL) {
2436 delete pNode[Index];
2437 }
2438
2439 if (VarIdStr[Index] != NULL) {
2440 delete VarIdStr[Index];
2441 }
2442 }
2443 }
2444
2445 VOID
2446 CVfrQuestionDB::RegisterOldTimeQuestion (
2447 IN INT8 *HourVarId,
2448 IN INT8 *MinuteVarId,
2449 IN INT8 *SecondVarId,
2450 IN OUT EFI_QUESTION_ID &QuestionId
2451 )
2452 {
2453 SVfrQuestionNode *pNode[3] = {NULL, };
2454 UINT32 Index;
2455
2456 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
2457 return;
2458 }
2459
2460 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
2461 goto Err;
2462 }
2463 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
2464 goto Err;
2465 }
2466 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
2467 goto Err;
2468 }
2469
2470 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2471 QuestionId = GetFreeQuestionId ();
2472 } else {
2473 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2474 goto Err;
2475 }
2476 MarkQuestionIdUsed (QuestionId);
2477 }
2478
2479 pNode[0]->mQuestionId = QuestionId;
2480 pNode[1]->mQuestionId = QuestionId;
2481 pNode[2]->mQuestionId = QuestionId;
2482 pNode[0]->mNext = pNode[1];
2483 pNode[1]->mNext = pNode[2];
2484 pNode[2]->mNext = mQuestionList;
2485 mQuestionList = pNode[0];
2486
2487 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2488 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2489 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2490
2491 return;
2492
2493 Err:
2494 for (Index = 0; Index < 3; Index++) {
2495 if (pNode[Index] != NULL) {
2496 delete pNode[Index];
2497 }
2498 }
2499 QuestionId = EFI_QUESTION_ID_INVALID;
2500 }
2501
2502 VOID
2503 CVfrQuestionDB::RegisterNewTimeQuestion (
2504 IN INT8 *Name,
2505 IN INT8 *BaseVarId,
2506 IN OUT EFI_QUESTION_ID &QuestionId
2507 )
2508 {
2509 SVfrQuestionNode *pNode[3] = {NULL, };
2510 UINT32 Len;
2511 INT8 *VarIdStr[3] = {NULL, };
2512 INT8 Index;
2513
2514 if (BaseVarId == NULL) {
2515 return;
2516 }
2517
2518 Len = strlen (BaseVarId);
2519
2520 VarIdStr[0] = new INT8[Len + strlen (".Hour") + 1];
2521 if (VarIdStr[0] != NULL) {
2522 strcpy (VarIdStr[0], BaseVarId);
2523 strcat (VarIdStr[0], ".Hour");
2524 }
2525 VarIdStr[1] = new INT8[Len + strlen (".Minute") + 1];
2526 if (VarIdStr[1] != NULL) {
2527 strcpy (VarIdStr[1], BaseVarId);
2528 strcat (VarIdStr[1], ".Minute");
2529 }
2530 VarIdStr[2] = new INT8[Len + strlen (".Second") + 1];
2531 if (VarIdStr[2] != NULL) {
2532 strcpy (VarIdStr[2], BaseVarId);
2533 strcat (VarIdStr[2], ".Second");
2534 }
2535
2536 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
2537 goto Err;
2538 }
2539 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
2540 goto Err;
2541 }
2542 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
2543 goto Err;
2544 }
2545
2546 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2547 QuestionId = GetFreeQuestionId ();
2548 } else {
2549 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2550 goto Err;
2551 }
2552 MarkQuestionIdUsed (QuestionId);
2553 }
2554
2555 pNode[0]->mQuestionId = QuestionId;
2556 pNode[1]->mQuestionId = QuestionId;
2557 pNode[2]->mQuestionId = QuestionId;
2558 pNode[0]->mNext = pNode[1];
2559 pNode[1]->mNext = pNode[2];
2560 pNode[2]->mNext = mQuestionList;
2561 mQuestionList = pNode[0];
2562
2563 for (Index = 0; Index < 3; Index++) {
2564 if (VarIdStr[Index] != NULL) {
2565 delete VarIdStr[Index];
2566 }
2567 }
2568
2569 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2570 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2571 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2572
2573 return;
2574
2575 Err:
2576 for (Index = 0; Index < 3; Index++) {
2577 if (pNode[Index] != NULL) {
2578 delete pNode[Index];
2579 }
2580
2581 if (VarIdStr[Index] != NULL) {
2582 delete VarIdStr[Index];
2583 }
2584 }
2585 }
2586
2587 EFI_VFR_RETURN_CODE
2588 CVfrQuestionDB::UpdateQuestionId (
2589 IN EFI_QUESTION_ID QId,
2590 IN EFI_QUESTION_ID NewQId
2591 )
2592 {
2593 SVfrQuestionNode *pNode = NULL;
2594
2595 if (ChekQuestionIdFree (NewQId) == FALSE) {
2596 return VFR_RETURN_REDEFINED;
2597 }
2598
2599 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2600 if (pNode->mQuestionId == QId) {
2601 break;
2602 }
2603 }
2604
2605 if (pNode == NULL) {
2606 return VFR_RETURN_UNDEFINED;
2607 }
2608
2609 MarkQuestionIdUnused (QId);
2610 pNode->mQuestionId = NewQId;
2611 MarkQuestionIdUsed (NewQId);
2612
2613 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
2614
2615 return VFR_RETURN_SUCCESS;
2616 }
2617
2618 VOID
2619 CVfrQuestionDB::GetQuestionId (
2620 IN INT8 *Name,
2621 IN INT8 *VarIdStr,
2622 OUT EFI_QUESTION_ID &QuestionId,
2623 OUT UINT32 &BitMask
2624 )
2625 {
2626 SVfrQuestionNode *pNode;
2627
2628 QuestionId = EFI_QUESTION_ID_INVALID;
2629 BitMask = 0x00000000;
2630
2631 if ((Name == NULL) && (VarIdStr == NULL)) {
2632 return ;
2633 }
2634
2635 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2636 if (Name != NULL) {
2637 if (strcmp (pNode->mName, Name) != 0) {
2638 continue;
2639 }
2640 }
2641
2642 if (VarIdStr != NULL) {
2643 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
2644 continue;
2645 }
2646 }
2647
2648 QuestionId = pNode->mQuestionId;
2649 BitMask = pNode->mBitMask;
2650 break;
2651 }
2652
2653 return ;
2654 }
2655
2656 EFI_VFR_RETURN_CODE
2657 CVfrQuestionDB::FindQuestion (
2658 IN EFI_QUESTION_ID QuestionId
2659 )
2660 {
2661 SVfrQuestionNode *pNode;
2662
2663 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2664 return VFR_RETURN_INVALID_PARAMETER;
2665 }
2666
2667 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2668 if (pNode->mQuestionId == QuestionId) {
2669 return VFR_RETURN_SUCCESS;
2670 }
2671 }
2672
2673 return VFR_RETURN_UNDEFINED;
2674 }
2675
2676 EFI_VFR_RETURN_CODE
2677 CVfrQuestionDB::FindQuestion (
2678 IN INT8 *Name
2679 )
2680 {
2681 SVfrQuestionNode *pNode;
2682
2683 if (Name == NULL) {
2684 return VFR_RETURN_FATAL_ERROR;
2685 }
2686
2687 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2688 if (strcmp (pNode->mName, Name) == 0) {
2689 return VFR_RETURN_SUCCESS;
2690 }
2691 }
2692
2693 return VFR_RETURN_UNDEFINED;
2694 }
2695