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