]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
3797cd822841d2f5eaa4c78fecdeef6428539be4
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
1 /** @file
2
3 Vfr common library functions.
4
5 Copyright (c) 2004 - 2008, 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 return VFR_RETURN_SUCCESS;
626 case ']':
627 return VFR_RETURN_DATA_STRING_ERROR;
628 }
629
630 return VFR_RETURN_SUCCESS;
631 }
632
633 EFI_VFR_RETURN_CODE
634 CVfrVarDataTypeDB::GetTypeField (
635 IN CHAR8 *FName,
636 IN SVfrDataType *Type,
637 OUT SVfrDataField *&Field
638 )
639 {
640 SVfrDataField *pField = NULL;
641
642 if ((FName == NULL) && (Type == NULL)) {
643 return VFR_RETURN_FATAL_ERROR;
644 }
645
646 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
647 if (strcmp (pField->mFieldName, FName) == 0) {
648 Field = pField;
649 return VFR_RETURN_SUCCESS;
650 }
651 }
652
653 return VFR_RETURN_UNDEFINED;
654 }
655
656 EFI_VFR_RETURN_CODE
657 CVfrVarDataTypeDB::GetFieldOffset (
658 IN SVfrDataField *Field,
659 IN UINT32 ArrayIdx,
660 OUT UINT32 &Offset
661 )
662 {
663 if (Field == NULL) {
664 return VFR_RETURN_FATAL_ERROR;
665 }
666
667 //
668 // Framework Vfr file Array Index is from 1.
669 // But Uefi Vfr file Array Index is from 0.
670 //
671 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
672 if (ArrayIdx == 0) {
673 return VFR_RETURN_ERROR_ARRARY_NUM;
674 }
675 ArrayIdx = ArrayIdx - 1;
676 }
677
678 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
679 return VFR_RETURN_ERROR_ARRARY_NUM;
680 }
681
682 //
683 // Be compatible with the current usage
684 // If ArraryIdx is not specified, the first one is used.
685 //
686 // if ArrayNum is larger than zero, ArraryIdx must be specified.
687 //
688 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
689 // return VFR_RETURN_ERROR_ARRARY_NUM;
690 // }
691 //
692
693 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
694 return VFR_RETURN_SUCCESS;
695 }
696
697 UINT8
698 CVfrVarDataTypeDB::GetFieldWidth (
699 IN SVfrDataField *Field
700 )
701 {
702 if (Field == NULL) {
703 return 0;
704 }
705
706 return Field->mFieldType->mType;
707 }
708
709 UINT32
710 CVfrVarDataTypeDB::GetFieldSize (
711 IN SVfrDataField *Field,
712 IN UINT32 ArrayIdx
713 )
714 {
715 if (Field == NULL) {
716 return VFR_RETURN_FATAL_ERROR;
717 }
718
719 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
720 return Field->mFieldType->mTotalSize * Field->mArrayNum;
721 } else {
722 return Field->mFieldType->mTotalSize;
723 }
724 }
725
726 VOID
727 CVfrVarDataTypeDB::InternalTypesListInit (
728 VOID
729 )
730 {
731 SVfrDataType *New = NULL;
732 UINT32 Index;
733
734 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
735 New = new SVfrDataType;
736 if (New != NULL) {
737 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
738 New->mType = gInternalTypesTable[Index].mType;
739 New->mAlign = gInternalTypesTable[Index].mAlign;
740 New->mTotalSize = gInternalTypesTable[Index].mSize;
741 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
742 SVfrDataField *pYearField = new SVfrDataField;
743 SVfrDataField *pMonthField = new SVfrDataField;
744 SVfrDataField *pDayField = new SVfrDataField;
745
746 strcpy (pYearField->mFieldName, "Year");
747 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
748 pYearField->mOffset = 0;
749 pYearField->mNext = pMonthField;
750 pYearField->mArrayNum = 0;
751
752 strcpy (pMonthField->mFieldName, "Month");
753 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
754 pMonthField->mOffset = 2;
755 pMonthField->mNext = pDayField;
756 pMonthField->mArrayNum = 0;
757
758 strcpy (pDayField->mFieldName, "Day");
759 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
760 pDayField->mOffset = 3;
761 pDayField->mNext = NULL;
762 pDayField->mArrayNum = 0;
763
764 New->mMembers = pYearField;
765 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
766 SVfrDataField *pHoursField = new SVfrDataField;
767 SVfrDataField *pMinutesField = new SVfrDataField;
768 SVfrDataField *pSecondsField = new SVfrDataField;
769
770 strcpy (pHoursField->mFieldName, "Hours");
771 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
772 pHoursField->mOffset = 0;
773 pHoursField->mNext = pMinutesField;
774 pHoursField->mArrayNum = 0;
775
776 strcpy (pMinutesField->mFieldName, "Minutes");
777 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
778 pMinutesField->mOffset = 1;
779 pMinutesField->mNext = pSecondsField;
780 pMinutesField->mArrayNum = 0;
781
782 strcpy (pSecondsField->mFieldName, "Seconds");
783 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
784 pSecondsField->mOffset = 2;
785 pSecondsField->mNext = NULL;
786 pSecondsField->mArrayNum = 0;
787
788 New->mMembers = pHoursField;
789 } else {
790 New->mMembers = NULL;
791 }
792 New->mNext = NULL;
793 RegisterNewType (New);
794 New = NULL;
795 }
796 }
797 }
798
799 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
800 VOID
801 )
802 {
803 mDataTypeList = NULL;
804 mNewDataType = NULL;
805 mCurrDataField = NULL;
806 mPackAlign = DEFAULT_PACK_ALIGN;
807 mPackStack = NULL;
808 mFirstNewDataTypeName = NULL;
809
810 InternalTypesListInit ();
811 }
812
813 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
814 VOID
815 )
816 {
817 SVfrDataType *pType;
818 SVfrDataField *pField;
819 SVfrPackStackNode *pPack;
820
821 if (mNewDataType != NULL) {
822 delete mNewDataType;
823 }
824
825 while (mDataTypeList != NULL) {
826 pType = mDataTypeList;
827 mDataTypeList = mDataTypeList->mNext;
828 while(pType->mMembers != NULL) {
829 pField = pType->mMembers;
830 pType->mMembers = pType->mMembers->mNext;
831 delete pField;
832 }
833 delete pType;
834 }
835
836 while (mPackStack != NULL) {
837 pPack = mPackStack;
838 mPackStack = mPackStack->mNext;
839 delete pPack;
840 }
841 }
842
843 EFI_VFR_RETURN_CODE
844 CVfrVarDataTypeDB::Pack (
845 IN UINT32 LineNum,
846 IN UINT8 Action,
847 IN CHAR8 *Identifier,
848 IN UINT32 Number
849 )
850 {
851 UINT32 PackAlign;
852 CHAR8 Msg[MAX_STRING_LEN] = {0, };
853
854 if (Action & VFR_PACK_SHOW) {
855 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
856 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
857 }
858
859 if (Action & VFR_PACK_PUSH) {
860 SVfrPackStackNode *pNew = NULL;
861
862 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
863 return VFR_RETURN_FATAL_ERROR;
864 }
865 pNew->mNext = mPackStack;
866 mPackStack = pNew;
867 }
868
869 if (Action & VFR_PACK_POP) {
870 SVfrPackStackNode *pNode = NULL;
871
872 if (mPackStack == NULL) {
873 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
874 }
875
876 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
877 if (pNode->Match (Identifier) == TRUE) {
878 mPackAlign = pNode->mNumber;
879 mPackStack = pNode->mNext;
880 }
881 }
882 }
883
884 if (Action & VFR_PACK_ASSIGN) {
885 PackAlign = (Number > 1) ? Number + Number % 2 : Number;
886 if ((PackAlign == 0) || (PackAlign > 16)) {
887 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
888 } else {
889 mPackAlign = PackAlign;
890 }
891 }
892
893 return VFR_RETURN_SUCCESS;
894 }
895
896 VOID
897 CVfrVarDataTypeDB::DeclareDataTypeBegin (
898 VOID
899 )
900 {
901 SVfrDataType *pNewType = NULL;
902
903 pNewType = new SVfrDataType;
904 pNewType->mTypeName[0] = '\0';
905 pNewType->mType = EFI_IFR_TYPE_OTHER;
906 pNewType->mAlign = DEFAULT_ALIGN;
907 pNewType->mTotalSize = 0;
908 pNewType->mMembers = NULL;
909 pNewType->mNext = NULL;
910
911 mNewDataType = pNewType;
912 }
913
914 EFI_VFR_RETURN_CODE
915 CVfrVarDataTypeDB::SetNewTypeName (
916 IN CHAR8 *TypeName
917 )
918 {
919 SVfrDataType *pType;
920
921 if (mNewDataType == NULL) {
922 return VFR_RETURN_ERROR_SKIPED;
923 }
924 if (TypeName == NULL) {
925 return VFR_RETURN_FATAL_ERROR;
926 }
927 if (strlen(TypeName) >= MAX_NAME_LEN) {
928 return VFR_RETURN_INVALID_PARAMETER;
929 }
930
931 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
932 if (strcmp(pType->mTypeName, TypeName) == 0) {
933 return VFR_RETURN_REDEFINED;
934 }
935 }
936
937 strcpy(mNewDataType->mTypeName, TypeName);
938 return VFR_RETURN_SUCCESS;
939 }
940
941 EFI_VFR_RETURN_CODE
942 CVfrVarDataTypeDB::DataTypeAddField (
943 IN CHAR8 *FieldName,
944 IN CHAR8 *TypeName,
945 IN UINT32 ArrayNum
946 )
947 {
948 SVfrDataField *pNewField = NULL;
949 SVfrDataType *pFieldType = NULL;
950 SVfrDataField *pTmp;
951 UINT32 Align;
952
953 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
954
955 if (strlen (FieldName) >= MAX_NAME_LEN) {
956 return VFR_RETURN_INVALID_PARAMETER;
957 }
958
959 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
960 if (strcmp (pTmp->mFieldName, FieldName) == 0) {
961 return VFR_RETURN_REDEFINED;
962 }
963 }
964
965 Align = MIN (mPackAlign, pFieldType->mAlign);
966
967 if ((pNewField = new SVfrDataField) == NULL) {
968 return VFR_RETURN_OUT_FOR_RESOURCES;
969 }
970 strcpy (pNewField->mFieldName, FieldName);
971 pNewField->mFieldType = pFieldType;
972 pNewField->mArrayNum = ArrayNum;
973 if ((mNewDataType->mTotalSize % Align) == 0) {
974 pNewField->mOffset = mNewDataType->mTotalSize;
975 } else {
976 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
977 }
978 if (mNewDataType->mMembers == NULL) {
979 mNewDataType->mMembers = pNewField;
980 pNewField->mNext = NULL;
981 } else {
982 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
983 ;
984 pTmp->mNext = pNewField;
985 pNewField->mNext = NULL;
986 }
987
988 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
989 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
990
991 return VFR_RETURN_SUCCESS;
992 }
993
994 VOID
995 CVfrVarDataTypeDB::DeclareDataTypeEnd (
996 VOID
997 )
998 {
999 if (mNewDataType->mTypeName[0] == '\0') {
1000 return;
1001 }
1002
1003 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
1004 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
1005 }
1006
1007 RegisterNewType (mNewDataType);
1008 if (mFirstNewDataTypeName == NULL) {
1009 mFirstNewDataTypeName = mNewDataType->mTypeName;
1010 }
1011
1012 mNewDataType = NULL;
1013 }
1014
1015 EFI_VFR_RETURN_CODE
1016 CVfrVarDataTypeDB::GetDataType (
1017 IN CHAR8 *TypeName,
1018 OUT SVfrDataType **DataType
1019 )
1020 {
1021 SVfrDataType *pDataType = NULL;
1022
1023 if (TypeName == NULL) {
1024 return VFR_RETURN_ERROR_SKIPED;
1025 }
1026
1027 if (DataType == NULL) {
1028 return VFR_RETURN_FATAL_ERROR;
1029 }
1030
1031 *DataType = NULL;
1032
1033 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1034 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1035 *DataType = pDataType;
1036 return VFR_RETURN_SUCCESS;
1037 }
1038 }
1039
1040 return VFR_RETURN_UNDEFINED;
1041 }
1042
1043 EFI_VFR_RETURN_CODE
1044 CVfrVarDataTypeDB::GetDataTypeSize (
1045 IN UINT8 DataType,
1046 OUT UINT32 *Size
1047 )
1048 {
1049 SVfrDataType *pDataType = NULL;
1050
1051 if (Size == NULL) {
1052 return VFR_RETURN_FATAL_ERROR;
1053 }
1054
1055 *Size = 0;
1056 DataType = DataType & 0x0F;
1057
1058 //
1059 // For user defined data type, the size can't be got by this function.
1060 //
1061 if (DataType == EFI_IFR_TYPE_OTHER) {
1062 return VFR_RETURN_SUCCESS;
1063 }
1064
1065 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1066 if (DataType == pDataType->mType) {
1067 *Size = pDataType->mTotalSize;
1068 return VFR_RETURN_SUCCESS;
1069 }
1070 }
1071
1072 return VFR_RETURN_UNDEFINED;
1073 }
1074
1075 EFI_VFR_RETURN_CODE
1076 CVfrVarDataTypeDB::GetDataTypeSize (
1077 IN CHAR8 *TypeName,
1078 OUT UINT32 *Size
1079 )
1080 {
1081 SVfrDataType *pDataType = NULL;
1082
1083 if (Size == NULL) {
1084 return VFR_RETURN_FATAL_ERROR;
1085 }
1086
1087 *Size = 0;
1088
1089 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1090 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1091 *Size = pDataType->mTotalSize;
1092 return VFR_RETURN_SUCCESS;
1093 }
1094 }
1095
1096 return VFR_RETURN_UNDEFINED;
1097 }
1098
1099 EFI_VFR_RETURN_CODE
1100 CVfrVarDataTypeDB::GetDataFieldInfo (
1101 IN CHAR8 *VarStr,
1102 OUT UINT16 &Offset,
1103 OUT UINT8 &Type,
1104 OUT UINT32 &Size
1105 )
1106 {
1107 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
1108 UINT32 ArrayIdx, Tmp;
1109 SVfrDataType *pType = NULL;
1110 SVfrDataField *pField = NULL;
1111
1112 Offset = 0;
1113 Type = EFI_IFR_TYPE_OTHER;
1114 Size = 0;
1115
1116 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
1117 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
1118
1119 //
1120 // if it is not struct data type
1121 //
1122 Type = pType->mType;
1123 Size = pType->mTotalSize;
1124
1125 while (*VarStr != '\0') {
1126 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
1127 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
1128 pType = pField->mFieldType;
1129 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
1130 Offset = (UINT16) (Offset + Tmp);
1131 Type = GetFieldWidth (pField);
1132 Size = GetFieldSize (pField, ArrayIdx);
1133 }
1134 return VFR_RETURN_SUCCESS;
1135 }
1136
1137 EFI_VFR_RETURN_CODE
1138 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1139 OUT CHAR8 ***NameList,
1140 OUT UINT32 *ListSize
1141 )
1142 {
1143 UINT32 Index;
1144 SVfrDataType *pType;
1145
1146 if ((NameList == NULL) || (ListSize == NULL)) {
1147 return VFR_RETURN_FATAL_ERROR;
1148 }
1149
1150 *NameList = NULL;
1151 *ListSize = 0;
1152
1153 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1154 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1155 (*ListSize)++;
1156 }
1157 }
1158
1159 if (*ListSize == 0) {
1160 return VFR_RETURN_SUCCESS;
1161 }
1162
1163 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
1164 *ListSize = 0;
1165 return VFR_RETURN_OUT_FOR_RESOURCES;
1166 }
1167
1168 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
1169 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1170 (*NameList)[Index] = pType->mTypeName;
1171 }
1172 }
1173 return VFR_RETURN_SUCCESS;
1174 }
1175
1176 BOOLEAN
1177 CVfrVarDataTypeDB::IsTypeNameDefined (
1178 IN CHAR8 *TypeName
1179 )
1180 {
1181 SVfrDataType *pType;
1182
1183 if (TypeName == NULL) {
1184 return FALSE;
1185 }
1186
1187 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1188 if (strcmp (pType->mTypeName, TypeName) == 0) {
1189 return TRUE;
1190 }
1191 }
1192
1193 return FALSE;
1194 }
1195
1196 VOID
1197 CVfrVarDataTypeDB::Dump (
1198 IN FILE *File
1199 )
1200 {
1201 SVfrDataType *pTNode;
1202 SVfrDataField *pFNode;
1203
1204 fprintf (File, "\n\n***************************************************************\n");
1205 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
1206 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1207 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1208 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
1209 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1210 if (pFNode->mArrayNum > 0) {
1211 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
1212 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
1213 } else {
1214 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
1215 pFNode->mFieldName, pFNode->mFieldType->mTypeName);
1216 }
1217 }
1218 fprintf (File, "\t\t};\n");
1219 fprintf (File, "---------------------------------------------------------------\n");
1220 }
1221 fprintf (File, "***************************************************************\n");
1222 }
1223
1224 #ifdef CVFR_VARDATATYPEDB_DEBUG
1225 VOID
1226 CVfrVarDataTypeDB::ParserDB (
1227 VOID
1228 )
1229 {
1230 SVfrDataType *pTNode;
1231 SVfrDataField *pFNode;
1232
1233 printf ("***************************************************************\n");
1234 printf ("\t\tmPackAlign = %x\n", mPackAlign);
1235 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1236 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1237 printf ("\t\tstruct %s {\n", pTNode->mTypeName);
1238 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1239 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
1240 }
1241 printf ("\t\t};\n");
1242 printf ("---------------------------------------------------------------\n");
1243 }
1244 printf ("***************************************************************\n");
1245 }
1246 #endif
1247
1248 SVfrVarStorageNode::SVfrVarStorageNode (
1249 IN EFI_GUID *Guid,
1250 IN CHAR8 *StoreName,
1251 IN EFI_VARSTORE_ID VarStoreId,
1252 IN EFI_STRING_ID VarName,
1253 IN UINT32 VarSize,
1254 IN BOOLEAN Flag
1255 )
1256 {
1257 if (Guid != NULL) {
1258 mGuid = *Guid;
1259 } else {
1260 memset (&Guid, 0, sizeof (EFI_GUID));
1261 }
1262 if (StoreName != NULL) {
1263 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1264 strcpy (mVarStoreName, StoreName);
1265 } else {
1266 mVarStoreName = NULL;
1267 }
1268 mNext = NULL;
1269 mVarStoreId = VarStoreId;
1270 mVarStoreType = EFI_VFR_VARSTORE_EFI;
1271 mStorageInfo.mEfiVar.mEfiVarName = VarName;
1272 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
1273 mAssignedFlag = Flag;
1274 }
1275
1276 SVfrVarStorageNode::SVfrVarStorageNode (
1277 IN EFI_GUID *Guid,
1278 IN CHAR8 *StoreName,
1279 IN EFI_VARSTORE_ID VarStoreId,
1280 IN SVfrDataType *DataType,
1281 IN BOOLEAN Flag
1282 )
1283 {
1284 if (Guid != NULL) {
1285 mGuid = *Guid;
1286 } else {
1287 memset (&Guid, 0, sizeof (EFI_GUID));
1288 }
1289 if (StoreName != NULL) {
1290 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1291 strcpy (mVarStoreName, StoreName);
1292 } else {
1293 mVarStoreName = NULL;
1294 }
1295 mNext = NULL;
1296 mVarStoreId = VarStoreId;
1297 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
1298 mStorageInfo.mDataType = DataType;
1299 mAssignedFlag = Flag;
1300 }
1301
1302 SVfrVarStorageNode::SVfrVarStorageNode (
1303 IN CHAR8 *StoreName,
1304 IN EFI_VARSTORE_ID VarStoreId
1305 )
1306 {
1307 if (StoreName != NULL) {
1308 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1309 strcpy (mVarStoreName, StoreName);
1310 } else {
1311 mVarStoreName = NULL;
1312 }
1313 mNext = NULL;
1314 mVarStoreId = VarStoreId;
1315 mVarStoreType = EFI_VFR_VARSTORE_NAME;
1316 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
1317 mStorageInfo.mNameSpace.mTableSize = 0;
1318 }
1319
1320 SVfrVarStorageNode::~SVfrVarStorageNode (
1321 VOID
1322 )
1323 {
1324 if (mVarStoreName != NULL) {
1325 delete mVarStoreName;
1326 }
1327
1328 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
1329 delete mStorageInfo.mNameSpace.mNameTable;
1330 }
1331 }
1332
1333 CVfrDataStorage::CVfrDataStorage (
1334 VOID
1335 )
1336 {
1337 UINT32 Index;
1338
1339 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1340 mFreeVarStoreIdBitMap[Index] = 0;
1341 }
1342
1343 // Question ID 0 is reserved.
1344 mFreeVarStoreIdBitMap[0] = 0x80000000;
1345
1346 mBufferVarStoreList = NULL;
1347 mEfiVarStoreList = NULL;
1348 mNameVarStoreList = NULL;
1349 mCurrVarStorageNode = NULL;
1350 mNewVarStorageNode = NULL;
1351 }
1352
1353 CVfrDataStorage::~CVfrDataStorage (
1354 VOID
1355 )
1356 {
1357 SVfrVarStorageNode *pNode;
1358
1359 while (mBufferVarStoreList != NULL) {
1360 pNode = mBufferVarStoreList;
1361 mBufferVarStoreList = mBufferVarStoreList->mNext;
1362 delete pNode;
1363 }
1364 while (mEfiVarStoreList != NULL) {
1365 pNode = mEfiVarStoreList;
1366 mEfiVarStoreList = mEfiVarStoreList->mNext;
1367 delete pNode;
1368 }
1369 while (mNameVarStoreList != NULL) {
1370 pNode = mNameVarStoreList;
1371 mNameVarStoreList = mNameVarStoreList->mNext;
1372 delete pNode;
1373 }
1374 if (mNewVarStorageNode != NULL) {
1375 delete mNewVarStorageNode;
1376 }
1377 }
1378
1379 EFI_VARSTORE_ID
1380 CVfrDataStorage::GetFreeVarStoreId (
1381 EFI_VFR_VARSTORE_TYPE VarType
1382 )
1383 {
1384 UINT32 Index, Mask, Offset;
1385
1386 //
1387 // Assign the different ID range for the different type VarStore to support Framework Vfr
1388 //
1389 Index = 0;
1390 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
1391 Index = 0;
1392 } else if (VarType == EFI_VFR_VARSTORE_EFI) {
1393 Index = 1;
1394 } else if (VarType == EFI_VFR_VARSTORE_NAME) {
1395 Index = 2;
1396 }
1397
1398 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1399 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1400 break;
1401 }
1402 }
1403
1404 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1405 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1406 mFreeVarStoreIdBitMap[Index] |= Mask;
1407 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1408 }
1409 }
1410
1411 return EFI_VARSTORE_ID_INVALID;
1412 }
1413
1414 BOOLEAN
1415 CVfrDataStorage::ChekVarStoreIdFree (
1416 IN EFI_VARSTORE_ID VarStoreId
1417 )
1418 {
1419 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1420 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1421
1422 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1423 }
1424
1425 VOID
1426 CVfrDataStorage::MarkVarStoreIdUsed (
1427 IN EFI_VARSTORE_ID VarStoreId
1428 )
1429 {
1430 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1431 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1432
1433 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1434 }
1435
1436 VOID
1437 CVfrDataStorage::MarkVarStoreIdUnused (
1438 IN EFI_VARSTORE_ID VarStoreId
1439 )
1440 {
1441 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1442 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1443
1444 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1445 }
1446
1447 EFI_VFR_RETURN_CODE
1448 CVfrDataStorage::DeclareNameVarStoreBegin (
1449 IN CHAR8 *StoreName
1450 )
1451 {
1452 SVfrVarStorageNode *pNode = NULL;
1453 EFI_VARSTORE_ID VarStoreId;
1454
1455 if (StoreName == NULL) {
1456 return VFR_RETURN_FATAL_ERROR;
1457 }
1458
1459 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1460 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1461 return VFR_RETURN_REDEFINED;
1462 }
1463 }
1464
1465 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1466 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1467 return VFR_RETURN_UNDEFINED;
1468 }
1469
1470 mNewVarStorageNode = pNode;
1471
1472 return VFR_RETURN_SUCCESS;
1473 }
1474
1475 EFI_VFR_RETURN_CODE
1476 CVfrDataStorage::NameTableAddItem (
1477 IN EFI_STRING_ID Item
1478 )
1479 {
1480 EFI_VARSTORE_ID *NewTable, *OldTable;
1481 UINT32 TableSize;
1482
1483 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1484 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1485
1486 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1487 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1488 return VFR_RETURN_OUT_FOR_RESOURCES;
1489 }
1490 memcpy (NewTable, OldTable, TableSize);
1491 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1492 }
1493
1494 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1495 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1496
1497 return VFR_RETURN_SUCCESS;
1498 }
1499
1500 EFI_VFR_RETURN_CODE
1501 CVfrDataStorage::DeclareNameVarStoreEnd (
1502 IN EFI_GUID *Guid
1503 )
1504 {
1505 mNewVarStorageNode->mGuid = *Guid;
1506 mNewVarStorageNode->mNext = mNameVarStoreList;
1507 mNameVarStoreList = mNewVarStorageNode;
1508
1509 mNewVarStorageNode = NULL;
1510
1511 return VFR_RETURN_SUCCESS;
1512 }
1513
1514 EFI_VFR_RETURN_CODE
1515 CVfrDataStorage::DeclareEfiVarStore (
1516 IN CHAR8 *StoreName,
1517 IN EFI_GUID *Guid,
1518 IN EFI_STRING_ID NameStrId,
1519 IN UINT32 VarSize,
1520 IN BOOLEAN Flag
1521 )
1522 {
1523 SVfrVarStorageNode *pNode;
1524 EFI_VARSTORE_ID VarStoreId;
1525
1526 if ((StoreName == NULL) || (Guid == NULL)) {
1527 return VFR_RETURN_FATAL_ERROR;
1528 }
1529
1530 if (VarSize > sizeof (UINT64)) {
1531 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1532 }
1533
1534 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1535 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1536 return VFR_RETURN_REDEFINED;
1537 }
1538 }
1539
1540 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
1541 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
1542 return VFR_RETURN_OUT_FOR_RESOURCES;
1543 }
1544
1545 pNode->mNext = mEfiVarStoreList;
1546 mEfiVarStoreList = pNode;
1547
1548 return VFR_RETURN_SUCCESS;
1549 }
1550
1551 EFI_VFR_RETURN_CODE
1552 CVfrDataStorage::DeclareBufferVarStore (
1553 IN CHAR8 *StoreName,
1554 IN EFI_GUID *Guid,
1555 IN CVfrVarDataTypeDB *DataTypeDB,
1556 IN CHAR8 *TypeName,
1557 IN EFI_VARSTORE_ID VarStoreId,
1558 IN BOOLEAN Flag
1559 )
1560 {
1561 SVfrVarStorageNode *pNew = NULL;
1562 SVfrDataType *pDataType = NULL;
1563
1564 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1565 return VFR_RETURN_FATAL_ERROR;
1566 }
1567
1568 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1569
1570 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1571 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1572 } else {
1573 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1574 return VFR_RETURN_VARSTOREID_REDEFINED;
1575 }
1576 MarkVarStoreIdUsed (VarStoreId);
1577 }
1578
1579 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
1580 return VFR_RETURN_OUT_FOR_RESOURCES;
1581 }
1582
1583 pNew->mNext = mBufferVarStoreList;
1584 mBufferVarStoreList = pNew;
1585
1586 if (gCVfrBufferConfig.Register(StoreName) != 0) {
1587 return VFR_RETURN_FATAL_ERROR;
1588 }
1589
1590 return VFR_RETURN_SUCCESS;
1591 }
1592
1593 EFI_VFR_RETURN_CODE
1594 CVfrDataStorage::GetVarStoreId (
1595 IN CHAR8 *StoreName,
1596 OUT EFI_VARSTORE_ID *VarStoreId
1597 )
1598 {
1599 SVfrVarStorageNode *pNode;
1600
1601 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1602 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1603 mCurrVarStorageNode = pNode;
1604 *VarStoreId = pNode->mVarStoreId;
1605 return VFR_RETURN_SUCCESS;
1606 }
1607 }
1608
1609 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1610 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1611 mCurrVarStorageNode = pNode;
1612 *VarStoreId = pNode->mVarStoreId;
1613 return VFR_RETURN_SUCCESS;
1614 }
1615 }
1616
1617 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1618 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1619 mCurrVarStorageNode = pNode;
1620 *VarStoreId = pNode->mVarStoreId;
1621 return VFR_RETURN_SUCCESS;
1622 }
1623 }
1624
1625 mCurrVarStorageNode = NULL;
1626 *VarStoreId = EFI_VARSTORE_ID_INVALID;
1627 return VFR_RETURN_UNDEFINED;
1628 }
1629
1630 EFI_VFR_RETURN_CODE
1631 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1632 IN CHAR8 *StoreName,
1633 OUT CHAR8 **DataTypeName
1634 )
1635 {
1636 SVfrVarStorageNode *pNode;
1637
1638 if ((StoreName == NULL) || (DataTypeName == NULL)) {
1639 return VFR_RETURN_FATAL_ERROR;
1640 }
1641
1642 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1643 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1644 break;
1645 }
1646 }
1647
1648 if (pNode == NULL) {
1649 return VFR_RETURN_UNDEFINED;
1650 }
1651
1652 if (pNode->mStorageInfo.mDataType == NULL) {
1653 return VFR_RETURN_FATAL_ERROR;
1654 }
1655
1656 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
1657 return VFR_RETURN_SUCCESS;
1658 }
1659
1660 EFI_VFR_RETURN_CODE
1661 CVfrDataStorage::GetVarStoreType (
1662 IN CHAR8 *StoreName,
1663 OUT EFI_VFR_VARSTORE_TYPE &VarStoreType
1664 )
1665 {
1666 SVfrVarStorageNode *pNode;
1667
1668 if (StoreName == NULL) {
1669 return VFR_RETURN_FATAL_ERROR;
1670 }
1671
1672 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1673 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1674 VarStoreType = pNode->mVarStoreType;
1675 return VFR_RETURN_SUCCESS;
1676 }
1677 }
1678
1679 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1680 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1681 VarStoreType = pNode->mVarStoreType;
1682 return VFR_RETURN_SUCCESS;
1683 }
1684 }
1685
1686 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1687 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1688 VarStoreType = pNode->mVarStoreType;
1689 return VFR_RETURN_SUCCESS;
1690 }
1691 }
1692
1693 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1694 return VFR_RETURN_UNDEFINED;
1695 }
1696
1697 EFI_VFR_VARSTORE_TYPE
1698 CVfrDataStorage::GetVarStoreType (
1699 IN EFI_VARSTORE_ID VarStoreId
1700 )
1701 {
1702 SVfrVarStorageNode *pNode;
1703 EFI_VFR_VARSTORE_TYPE VarStoreType;
1704
1705 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1706
1707 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1708 return VarStoreType;
1709 }
1710
1711 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1712 if (pNode->mVarStoreId == VarStoreId) {
1713 VarStoreType = pNode->mVarStoreType;
1714 return VarStoreType;
1715 }
1716 }
1717
1718 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1719 if (pNode->mVarStoreId == VarStoreId) {
1720 VarStoreType = pNode->mVarStoreType;
1721 return VarStoreType;
1722 }
1723 }
1724
1725 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1726 if (pNode->mVarStoreId == VarStoreId) {
1727 VarStoreType = pNode->mVarStoreType;
1728 return VarStoreType;
1729 }
1730 }
1731
1732 return VarStoreType;
1733 }
1734
1735 EFI_VFR_RETURN_CODE
1736 CVfrDataStorage::GetVarStoreName (
1737 IN EFI_VARSTORE_ID VarStoreId,
1738 OUT CHAR8 **VarStoreName
1739 )
1740 {
1741 SVfrVarStorageNode *pNode;
1742
1743 if (VarStoreName == NULL) {
1744 return VFR_RETURN_FATAL_ERROR;
1745 }
1746
1747 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1748 if (pNode->mVarStoreId == VarStoreId) {
1749 *VarStoreName = pNode->mVarStoreName;
1750 return VFR_RETURN_SUCCESS;
1751 }
1752 }
1753
1754 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1755 if (pNode->mVarStoreId == VarStoreId) {
1756 *VarStoreName = pNode->mVarStoreName;
1757 return VFR_RETURN_SUCCESS;
1758 }
1759 }
1760
1761 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1762 if (pNode->mVarStoreId == VarStoreId) {
1763 *VarStoreName = pNode->mVarStoreName;
1764 return VFR_RETURN_SUCCESS;
1765 }
1766 }
1767
1768 *VarStoreName = NULL;
1769 return VFR_RETURN_UNDEFINED;
1770 }
1771
1772 EFI_VFR_RETURN_CODE
1773 CVfrDataStorage::GetEfiVarStoreInfo (
1774 IN OUT EFI_VARSTORE_INFO *Info
1775 )
1776 {
1777 if (Info == NULL) {
1778 return VFR_RETURN_FATAL_ERROR;
1779 }
1780
1781 if (mCurrVarStorageNode == NULL) {
1782 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
1783 }
1784
1785 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
1786 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
1787 switch (Info->mVarTotalSize) {
1788 case 1:
1789 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
1790 break;
1791 case 2:
1792 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
1793 break;
1794 case 4:
1795 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
1796 break;
1797 case 8:
1798 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
1799 break;
1800 default :
1801 return VFR_RETURN_FATAL_ERROR;
1802 }
1803
1804 return VFR_RETURN_SUCCESS;
1805 }
1806
1807 EFI_VFR_RETURN_CODE
1808 CVfrDataStorage::GetNameVarStoreInfo (
1809 OUT EFI_VARSTORE_INFO *Info,
1810 IN UINT32 Index
1811 )
1812 {
1813 if (Info == NULL) {
1814 return VFR_RETURN_FATAL_ERROR;
1815 }
1816
1817 if (mCurrVarStorageNode == NULL) {
1818 return VFR_RETURN_GET_NVVARSTORE_ERROR;
1819 }
1820
1821 //
1822 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
1823 //
1824 if (VfrCompatibleMode) {
1825 if (Index == 0) {
1826 return VFR_RETURN_ERROR_ARRARY_NUM;
1827 }
1828 Index --;
1829 }
1830
1831 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
1832
1833 return VFR_RETURN_SUCCESS;
1834 }
1835
1836 EFI_VFR_RETURN_CODE
1837 CVfrDataStorage::BufferVarStoreRequestElementAdd (
1838 IN CHAR8 *StoreName,
1839 IN EFI_VARSTORE_INFO &Info
1840 )
1841 {
1842 SVfrVarStorageNode *pNode = NULL;
1843 EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;
1844
1845 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1846 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1847 break;
1848 }
1849 }
1850
1851 if (pNode == NULL) {
1852 return VFR_RETURN_UNDEFINED;
1853 }
1854
1855 gCVfrBufferConfig.Open ();
1856 Value.u8 = 0;
1857 if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
1858 return VFR_RETURN_FATAL_ERROR;
1859 }
1860 gCVfrBufferConfig.Close ();
1861
1862 return VFR_RETURN_SUCCESS;
1863 }
1864
1865 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
1866 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
1867 IN CHAR8 *RefName,
1868 IN EFI_STRING_ID DefaultStoreNameId,
1869 IN UINT16 DefaultId
1870 )
1871 {
1872 mObjBinAddr = ObjBinAddr;
1873
1874 if (RefName != NULL) {
1875 mRefName = new CHAR8[strlen (RefName) + 1];
1876 strcpy (mRefName, RefName);
1877 } else {
1878 mRefName = NULL;
1879 }
1880
1881 mNext = NULL;
1882 mDefaultId = DefaultId;
1883 mDefaultStoreNameId = DefaultStoreNameId;
1884 }
1885
1886 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
1887 VOID
1888 )
1889 {
1890 if (mRefName != NULL) {
1891 delete mRefName;
1892 }
1893 }
1894
1895 CVfrDefaultStore::CVfrDefaultStore (
1896 VOID
1897 )
1898 {
1899 mDefaultStoreList = NULL;
1900 }
1901
1902 CVfrDefaultStore::~CVfrDefaultStore (
1903 VOID
1904 )
1905 {
1906 SVfrDefaultStoreNode *pTmp = NULL;
1907
1908 while (mDefaultStoreList != NULL) {
1909 pTmp = mDefaultStoreList;
1910 mDefaultStoreList = mDefaultStoreList->mNext;
1911 delete pTmp;
1912 }
1913 }
1914
1915 EFI_VFR_RETURN_CODE
1916 CVfrDefaultStore::RegisterDefaultStore (
1917 IN CHAR8 *ObjBinAddr,
1918 IN CHAR8 *RefName,
1919 IN EFI_STRING_ID DefaultStoreNameId,
1920 IN UINT16 DefaultId
1921 )
1922 {
1923 SVfrDefaultStoreNode *pNode = NULL;
1924
1925 if (RefName == NULL) {
1926 return VFR_RETURN_FATAL_ERROR;
1927 }
1928
1929 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1930 if (strcmp (pNode->mRefName, RefName) == 0) {
1931 return VFR_RETURN_REDEFINED;
1932 }
1933 }
1934
1935 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
1936 return VFR_RETURN_OUT_FOR_RESOURCES;
1937 }
1938
1939 pNode->mNext = mDefaultStoreList;
1940 mDefaultStoreList = pNode;
1941
1942 return VFR_RETURN_SUCCESS;
1943 }
1944
1945 /*
1946 * assign new reference name or new default store name id only if
1947 * the original is invalid
1948 */
1949 EFI_VFR_RETURN_CODE
1950 CVfrDefaultStore::ReRegisterDefaultStoreById (
1951 IN UINT16 DefaultId,
1952 IN CHAR8 *RefName,
1953 IN EFI_STRING_ID DefaultStoreNameId
1954 )
1955 {
1956 SVfrDefaultStoreNode *pNode = NULL;
1957
1958 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1959 if (pNode->mDefaultId == DefaultId) {
1960 break;
1961 }
1962 }
1963
1964 if (pNode == NULL) {
1965 return VFR_RETURN_UNDEFINED;
1966 } else {
1967 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
1968 pNode->mDefaultStoreNameId = DefaultStoreNameId;
1969 if (pNode->mObjBinAddr != NULL) {
1970 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
1971 }
1972 } else {
1973 return VFR_RETURN_REDEFINED;
1974 }
1975
1976 if (RefName != NULL) {
1977 delete pNode->mRefName;
1978 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
1979 if (pNode->mRefName != NULL) {
1980 strcpy (pNode->mRefName, RefName);
1981 }
1982 }
1983 }
1984
1985 return VFR_RETURN_SUCCESS;
1986 }
1987
1988 BOOLEAN
1989 CVfrDefaultStore::DefaultIdRegistered (
1990 IN UINT16 DefaultId
1991 )
1992 {
1993 SVfrDefaultStoreNode *pNode = NULL;
1994
1995 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1996 if (pNode->mDefaultId == DefaultId) {
1997 return TRUE;
1998 }
1999 }
2000
2001 return FALSE;
2002 }
2003
2004 EFI_VFR_RETURN_CODE
2005 CVfrDefaultStore::GetDefaultId (
2006 IN CHAR8 *RefName,
2007 OUT UINT16 *DefaultId
2008 )
2009 {
2010 SVfrDefaultStoreNode *pTmp = NULL;
2011
2012 if (DefaultId == NULL) {
2013 return VFR_RETURN_FATAL_ERROR;
2014 }
2015
2016 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2017 if (strcmp (pTmp->mRefName, RefName) == 0) {
2018 *DefaultId = pTmp->mDefaultId;
2019 return VFR_RETURN_SUCCESS;
2020 }
2021 }
2022
2023 return VFR_RETURN_UNDEFINED;
2024 }
2025
2026 EFI_VFR_RETURN_CODE
2027 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2028 IN EFI_VARSTORE_ID DefaultId,
2029 IN EFI_VARSTORE_INFO &Info,
2030 IN CHAR8 *VarStoreName,
2031 IN UINT8 Type,
2032 IN EFI_IFR_TYPE_VALUE Value
2033 )
2034 {
2035 SVfrDefaultStoreNode *pNode = NULL;
2036 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2037 INTN Returnvalue = 0;
2038
2039 if (VarStoreName == NULL) {
2040 return VFR_RETURN_FATAL_ERROR;
2041 }
2042
2043 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2044 if (pNode->mDefaultId == DefaultId) {
2045 break;
2046 }
2047 }
2048
2049 if (pNode == NULL) {
2050 return VFR_RETURN_UNDEFINED;
2051 }
2052
2053 gCVfrBufferConfig.Open ();
2054
2055 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2056 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {
2057 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2058 goto WriteError;
2059 }
2060 }
2061
2062 gCVfrBufferConfig.Close ();
2063
2064 return VFR_RETURN_SUCCESS;
2065
2066 WriteError:
2067 gCVfrBufferConfig.Close ();
2068 return (EFI_VFR_RETURN_CODE)Returnvalue;
2069 }
2070
2071 SVfrRuleNode::SVfrRuleNode (
2072 IN CHAR8 *RuleName,
2073 IN UINT8 RuleId
2074 )
2075 {
2076 if (RuleName != NULL) {
2077 mRuleName = new CHAR8[strlen (RuleName) + 1];
2078 strcpy (mRuleName, RuleName);
2079 } else {
2080 mRuleName = NULL;
2081 }
2082
2083 mNext = NULL;
2084 mRuleId = RuleId;
2085 }
2086
2087 SVfrRuleNode::~SVfrRuleNode (
2088 VOID
2089 )
2090 {
2091 if (mRuleName != NULL) {
2092 delete mRuleName;
2093 }
2094 }
2095
2096 CVfrRulesDB::CVfrRulesDB ()
2097 {
2098 mRuleList = NULL;
2099 mFreeRuleId = EFI_VARSTORE_ID_START;
2100 }
2101
2102 CVfrRulesDB::~CVfrRulesDB ()
2103 {
2104 SVfrRuleNode *pNode;
2105
2106 while(mRuleList != NULL) {
2107 pNode = mRuleList;
2108 mRuleList = mRuleList->mNext;
2109 delete pNode;
2110 }
2111 }
2112
2113 VOID
2114 CVfrRulesDB::RegisterRule (
2115 IN CHAR8 *RuleName
2116 )
2117 {
2118 SVfrRuleNode *pNew;
2119
2120 if (RuleName == NULL) {
2121 return ;
2122 }
2123
2124 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2125 return ;
2126 }
2127
2128 mFreeRuleId++;
2129
2130 pNew->mNext = mRuleList;
2131 mRuleList = pNew;
2132 }
2133
2134 UINT8
2135 CVfrRulesDB::GetRuleId (
2136 IN CHAR8 *RuleName
2137 )
2138 {
2139 SVfrRuleNode *pNode;
2140
2141 if (RuleName == NULL) {
2142 return EFI_RULE_ID_INVALID;
2143 }
2144
2145 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2146 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2147 return pNode->mRuleId;
2148 }
2149 }
2150
2151 return EFI_RULE_ID_INVALID;
2152 }
2153
2154 CVfrRulesDB gCVfrRulesDB;
2155
2156 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2157 VOID
2158 )
2159 {
2160 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2161 mInfo.mVarName = EFI_STRING_ID_INVALID;
2162 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2163 mVarType = EFI_IFR_TYPE_OTHER;
2164 mVarTotalSize = 0;
2165 }
2166
2167 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2168 IN EFI_VARSTORE_INFO &Info
2169 )
2170 {
2171 mVarStoreId = Info.mVarStoreId;
2172 mInfo.mVarName = Info.mInfo.mVarName;
2173 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2174 mVarType = Info.mVarType;
2175 mVarTotalSize = Info.mVarTotalSize;
2176 }
2177
2178 BOOLEAN
2179 EFI_VARSTORE_INFO::operator == (
2180 IN EFI_VARSTORE_INFO *Info
2181 )
2182 {
2183 if ((mVarStoreId == Info->mVarStoreId) &&
2184 (mInfo.mVarName == Info->mInfo.mVarName) &&
2185 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2186 (mVarType == Info->mVarType) &&
2187 (mVarTotalSize == Info->mVarTotalSize)) {
2188 return TRUE;
2189 }
2190
2191 return FALSE;
2192 }
2193
2194 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2195
2196 EFI_QUESTION_ID
2197 CVfrQuestionDB::GetFreeQuestionId (
2198 VOID
2199 )
2200 {
2201 UINT32 Index, Mask, Offset;
2202
2203 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2204 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2205 break;
2206 }
2207 }
2208
2209 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2210 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2211 mFreeQIdBitMap[Index] |= Mask;
2212 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2213 }
2214 }
2215
2216 return EFI_QUESTION_ID_INVALID;
2217 }
2218
2219 BOOLEAN
2220 CVfrQuestionDB::ChekQuestionIdFree (
2221 IN EFI_QUESTION_ID QId
2222 )
2223 {
2224 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2225 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2226
2227 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2228 }
2229
2230 VOID
2231 CVfrQuestionDB::MarkQuestionIdUsed (
2232 IN EFI_QUESTION_ID QId
2233 )
2234 {
2235 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2236 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2237
2238 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2239 }
2240
2241 VOID
2242 CVfrQuestionDB::MarkQuestionIdUnused (
2243 IN EFI_QUESTION_ID QId
2244 )
2245 {
2246 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2247 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2248
2249 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2250 }
2251
2252 SVfrQuestionNode::SVfrQuestionNode (
2253 IN CHAR8 *Name,
2254 IN CHAR8 *VarIdStr,
2255 IN UINT32 BitMask
2256 )
2257 {
2258 mName = NULL;
2259 mVarIdStr = NULL;
2260 mQuestionId = EFI_QUESTION_ID_INVALID;
2261 mBitMask = BitMask;
2262 mNext = NULL;
2263 mQtype = QUESTION_NORMAL;
2264
2265 if (Name == NULL) {
2266 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2267 strcpy (mName, "$DEFAULT");
2268 } else {
2269 mName = new CHAR8[strlen (Name) + 1];
2270 strcpy (mName, Name);
2271 }
2272
2273 if (VarIdStr != NULL) {
2274 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2275 strcpy (mVarIdStr, VarIdStr);
2276 } else {
2277 mVarIdStr = new CHAR8[strlen ("$") + 1];
2278 strcpy (mVarIdStr, "$");
2279 }
2280 }
2281
2282 SVfrQuestionNode::~SVfrQuestionNode (
2283 VOID
2284 )
2285 {
2286 if (mName != NULL) {
2287 delete mName;
2288 }
2289
2290 if (mVarIdStr != NULL) {
2291 delete mVarIdStr;
2292 }
2293 }
2294
2295 CVfrQuestionDB::CVfrQuestionDB ()
2296 {
2297 UINT32 Index;
2298
2299 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2300 mFreeQIdBitMap[Index] = 0;
2301 }
2302
2303 // Question ID 0 is reserved.
2304 mFreeQIdBitMap[0] = 0x80000000;
2305 mQuestionList = NULL;
2306 }
2307
2308 CVfrQuestionDB::~CVfrQuestionDB ()
2309 {
2310 SVfrQuestionNode *pNode;
2311
2312 while (mQuestionList != NULL) {
2313 pNode = mQuestionList;
2314 mQuestionList = mQuestionList->mNext;
2315 delete pNode;
2316 }
2317 }
2318
2319 //
2320 // Reset to init state
2321 //
2322 VOID
2323 CVfrQuestionDB::ResetInit(
2324 IN VOID
2325 )
2326 {
2327 UINT32 Index;
2328 SVfrQuestionNode *pNode;
2329
2330 while (mQuestionList != NULL) {
2331 pNode = mQuestionList;
2332 mQuestionList = mQuestionList->mNext;
2333 delete pNode;
2334 }
2335
2336 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2337 mFreeQIdBitMap[Index] = 0;
2338 }
2339
2340 // Question ID 0 is reserved.
2341 mFreeQIdBitMap[0] = 0x80000000;
2342 mQuestionList = NULL;
2343 }
2344
2345 VOID
2346 CVfrQuestionDB::PrintAllQuestion (
2347 VOID
2348 )
2349 {
2350 SVfrQuestionNode *pNode = NULL;
2351
2352 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2353 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2354 }
2355 }
2356
2357 EFI_VFR_RETURN_CODE
2358 CVfrQuestionDB::RegisterQuestion (
2359 IN CHAR8 *Name,
2360 IN CHAR8 *VarIdStr,
2361 IN OUT EFI_QUESTION_ID &QuestionId
2362 )
2363 {
2364 SVfrQuestionNode *pNode = NULL;
2365
2366 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2367 return VFR_RETURN_REDEFINED;
2368 }
2369
2370 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2371 return VFR_RETURN_OUT_FOR_RESOURCES;
2372 }
2373
2374 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2375 QuestionId = GetFreeQuestionId ();
2376 } else {
2377 //
2378 // For Framework Vfr, don't check question ID conflict.
2379 //
2380 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
2381 delete pNode;
2382 return VFR_RETURN_QUESTIONID_REDEFINED;
2383 }
2384 MarkQuestionIdUsed (QuestionId);
2385 }
2386 pNode->mQuestionId = QuestionId;
2387
2388 pNode->mNext = mQuestionList;
2389 mQuestionList = pNode;
2390
2391 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2392
2393 return VFR_RETURN_SUCCESS;
2394 }
2395
2396 VOID
2397 CVfrQuestionDB::RegisterOldDateQuestion (
2398 IN CHAR8 *YearVarId,
2399 IN CHAR8 *MonthVarId,
2400 IN CHAR8 *DayVarId,
2401 IN OUT EFI_QUESTION_ID &QuestionId
2402 )
2403 {
2404 SVfrQuestionNode *pNode[3] = {NULL, };
2405 UINT32 Index;
2406
2407 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2408 return;
2409 }
2410
2411 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2412 goto Err;
2413 }
2414 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2415 goto Err;
2416 }
2417 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2418 goto Err;
2419 }
2420
2421 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2422 QuestionId = GetFreeQuestionId ();
2423 } else {
2424 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2425 goto Err;
2426 }
2427 MarkQuestionIdUsed (QuestionId);
2428 }
2429
2430 pNode[0]->mQuestionId = QuestionId;
2431 pNode[1]->mQuestionId = QuestionId;
2432 pNode[2]->mQuestionId = QuestionId;
2433 pNode[0]->mQtype = QUESTION_DATE;
2434 pNode[1]->mQtype = QUESTION_DATE;
2435 pNode[2]->mQtype = QUESTION_DATE;
2436 pNode[0]->mNext = pNode[1];
2437 pNode[1]->mNext = pNode[2];
2438 pNode[2]->mNext = mQuestionList;
2439 mQuestionList = pNode[0];
2440
2441 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2442 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2443 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2444
2445 return;
2446
2447 Err:
2448 for (Index = 0; Index < 3; Index++) {
2449 if (pNode[Index] != NULL) {
2450 delete pNode[Index];
2451 }
2452 }
2453 QuestionId = EFI_QUESTION_ID_INVALID;
2454 }
2455
2456 VOID
2457 CVfrQuestionDB::RegisterNewDateQuestion (
2458 IN CHAR8 *Name,
2459 IN CHAR8 *BaseVarId,
2460 IN OUT EFI_QUESTION_ID &QuestionId
2461 )
2462 {
2463 SVfrQuestionNode *pNode[3] = {NULL, };
2464 UINT32 Len;
2465 CHAR8 *VarIdStr[3] = {NULL, };
2466 CHAR8 Index;
2467
2468 if (BaseVarId == NULL) {
2469 return;
2470 }
2471
2472 Len = strlen (BaseVarId);
2473
2474 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2475 if (VarIdStr[0] != NULL) {
2476 strcpy (VarIdStr[0], BaseVarId);
2477 strcat (VarIdStr[0], ".Year");
2478 }
2479 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2480 if (VarIdStr[1] != NULL) {
2481 strcpy (VarIdStr[1], BaseVarId);
2482 strcat (VarIdStr[1], ".Month");
2483 }
2484 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2485 if (VarIdStr[2] != NULL) {
2486 strcpy (VarIdStr[2], BaseVarId);
2487 strcat (VarIdStr[2], ".Day");
2488 }
2489
2490 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2491 goto Err;
2492 }
2493 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2494 goto Err;
2495 }
2496 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2497 goto Err;
2498 }
2499
2500 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2501 QuestionId = GetFreeQuestionId ();
2502 } else {
2503 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2504 goto Err;
2505 }
2506 MarkQuestionIdUsed (QuestionId);
2507 }
2508
2509 pNode[0]->mQuestionId = QuestionId;
2510 pNode[1]->mQuestionId = QuestionId;
2511 pNode[2]->mQuestionId = QuestionId;
2512 pNode[0]->mQtype = QUESTION_DATE;
2513 pNode[1]->mQtype = QUESTION_DATE;
2514 pNode[2]->mQtype = QUESTION_DATE;
2515 pNode[0]->mNext = pNode[1];
2516 pNode[1]->mNext = pNode[2];
2517 pNode[2]->mNext = mQuestionList;
2518 mQuestionList = pNode[0];
2519
2520 for (Index = 0; Index < 3; Index++) {
2521 if (VarIdStr[Index] != NULL) {
2522 delete VarIdStr[Index];
2523 }
2524 }
2525
2526 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2527 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2528 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2529
2530 return;
2531
2532 Err:
2533 for (Index = 0; Index < 3; Index++) {
2534 if (pNode[Index] != NULL) {
2535 delete pNode[Index];
2536 }
2537
2538 if (VarIdStr[Index] != NULL) {
2539 delete VarIdStr[Index];
2540 }
2541 }
2542 }
2543
2544 VOID
2545 CVfrQuestionDB::RegisterOldTimeQuestion (
2546 IN CHAR8 *HourVarId,
2547 IN CHAR8 *MinuteVarId,
2548 IN CHAR8 *SecondVarId,
2549 IN OUT EFI_QUESTION_ID &QuestionId
2550 )
2551 {
2552 SVfrQuestionNode *pNode[3] = {NULL, };
2553 UINT32 Index;
2554
2555 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
2556 return;
2557 }
2558
2559 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
2560 goto Err;
2561 }
2562 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
2563 goto Err;
2564 }
2565 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
2566 goto Err;
2567 }
2568
2569 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2570 QuestionId = GetFreeQuestionId ();
2571 } else {
2572 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2573 goto Err;
2574 }
2575 MarkQuestionIdUsed (QuestionId);
2576 }
2577
2578 pNode[0]->mQuestionId = QuestionId;
2579 pNode[1]->mQuestionId = QuestionId;
2580 pNode[2]->mQuestionId = QuestionId;
2581 pNode[0]->mQtype = QUESTION_TIME;
2582 pNode[1]->mQtype = QUESTION_TIME;
2583 pNode[2]->mQtype = QUESTION_TIME;
2584 pNode[0]->mNext = pNode[1];
2585 pNode[1]->mNext = pNode[2];
2586 pNode[2]->mNext = mQuestionList;
2587 mQuestionList = pNode[0];
2588
2589 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2590 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2591 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2592
2593 return;
2594
2595 Err:
2596 for (Index = 0; Index < 3; Index++) {
2597 if (pNode[Index] != NULL) {
2598 delete pNode[Index];
2599 }
2600 }
2601 QuestionId = EFI_QUESTION_ID_INVALID;
2602 }
2603
2604 VOID
2605 CVfrQuestionDB::RegisterNewTimeQuestion (
2606 IN CHAR8 *Name,
2607 IN CHAR8 *BaseVarId,
2608 IN OUT EFI_QUESTION_ID &QuestionId
2609 )
2610 {
2611 SVfrQuestionNode *pNode[3] = {NULL, };
2612 UINT32 Len;
2613 CHAR8 *VarIdStr[3] = {NULL, };
2614 CHAR8 Index;
2615
2616 if (BaseVarId == NULL) {
2617 return;
2618 }
2619
2620 Len = strlen (BaseVarId);
2621
2622 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2623 if (VarIdStr[0] != NULL) {
2624 strcpy (VarIdStr[0], BaseVarId);
2625 strcat (VarIdStr[0], ".Hour");
2626 }
2627 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2628 if (VarIdStr[1] != NULL) {
2629 strcpy (VarIdStr[1], BaseVarId);
2630 strcat (VarIdStr[1], ".Minute");
2631 }
2632 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2633 if (VarIdStr[2] != NULL) {
2634 strcpy (VarIdStr[2], BaseVarId);
2635 strcat (VarIdStr[2], ".Second");
2636 }
2637
2638 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
2639 goto Err;
2640 }
2641 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
2642 goto Err;
2643 }
2644 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
2645 goto Err;
2646 }
2647
2648 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2649 QuestionId = GetFreeQuestionId ();
2650 } else {
2651 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2652 goto Err;
2653 }
2654 MarkQuestionIdUsed (QuestionId);
2655 }
2656
2657 pNode[0]->mQuestionId = QuestionId;
2658 pNode[1]->mQuestionId = QuestionId;
2659 pNode[2]->mQuestionId = QuestionId;
2660 pNode[0]->mQtype = QUESTION_TIME;
2661 pNode[1]->mQtype = QUESTION_TIME;
2662 pNode[2]->mQtype = QUESTION_TIME;
2663 pNode[0]->mNext = pNode[1];
2664 pNode[1]->mNext = pNode[2];
2665 pNode[2]->mNext = mQuestionList;
2666 mQuestionList = pNode[0];
2667
2668 for (Index = 0; Index < 3; Index++) {
2669 if (VarIdStr[Index] != NULL) {
2670 delete VarIdStr[Index];
2671 }
2672 }
2673
2674 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2675 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2676 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2677
2678 return;
2679
2680 Err:
2681 for (Index = 0; Index < 3; Index++) {
2682 if (pNode[Index] != NULL) {
2683 delete pNode[Index];
2684 }
2685
2686 if (VarIdStr[Index] != NULL) {
2687 delete VarIdStr[Index];
2688 }
2689 }
2690 }
2691
2692 EFI_VFR_RETURN_CODE
2693 CVfrQuestionDB::UpdateQuestionId (
2694 IN EFI_QUESTION_ID QId,
2695 IN EFI_QUESTION_ID NewQId
2696 )
2697 {
2698 SVfrQuestionNode *pNode = NULL;
2699
2700 if (QId == NewQId) {
2701 // don't update
2702 return VFR_RETURN_SUCCESS;
2703 }
2704
2705 //
2706 // For Framework Vfr, don't check question ID conflict.
2707 //
2708 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
2709 return VFR_RETURN_REDEFINED;
2710 }
2711
2712 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2713 if (pNode->mQuestionId == QId) {
2714 break;
2715 }
2716 }
2717
2718 if (pNode == NULL) {
2719 return VFR_RETURN_UNDEFINED;
2720 }
2721
2722 MarkQuestionIdUnused (QId);
2723 pNode->mQuestionId = NewQId;
2724 MarkQuestionIdUsed (NewQId);
2725
2726 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
2727
2728 return VFR_RETURN_SUCCESS;
2729 }
2730
2731 VOID
2732 CVfrQuestionDB::GetQuestionId (
2733 IN CHAR8 *Name,
2734 IN CHAR8 *VarIdStr,
2735 OUT EFI_QUESTION_ID &QuestionId,
2736 OUT UINT32 &BitMask,
2737 OUT EFI_QUESION_TYPE *QType
2738 )
2739 {
2740 SVfrQuestionNode *pNode;
2741
2742 QuestionId = EFI_QUESTION_ID_INVALID;
2743 BitMask = 0x00000000;
2744 if (QType != NULL) {
2745 *QType = QUESTION_NORMAL;
2746 }
2747
2748 if ((Name == NULL) && (VarIdStr == NULL)) {
2749 return ;
2750 }
2751
2752 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2753 if (Name != NULL) {
2754 if (strcmp (pNode->mName, Name) != 0) {
2755 continue;
2756 }
2757 }
2758
2759 if (VarIdStr != NULL) {
2760 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
2761 continue;
2762 }
2763 }
2764
2765 QuestionId = pNode->mQuestionId;
2766 BitMask = pNode->mBitMask;
2767 if (QType != NULL) {
2768 *QType = pNode->mQtype;
2769 }
2770 break;
2771 }
2772
2773 return ;
2774 }
2775
2776 EFI_VFR_RETURN_CODE
2777 CVfrQuestionDB::FindQuestion (
2778 IN EFI_QUESTION_ID QuestionId
2779 )
2780 {
2781 SVfrQuestionNode *pNode;
2782
2783 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2784 return VFR_RETURN_INVALID_PARAMETER;
2785 }
2786
2787 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2788 if (pNode->mQuestionId == QuestionId) {
2789 return VFR_RETURN_SUCCESS;
2790 }
2791 }
2792
2793 return VFR_RETURN_UNDEFINED;
2794 }
2795
2796 EFI_VFR_RETURN_CODE
2797 CVfrQuestionDB::FindQuestion (
2798 IN CHAR8 *Name
2799 )
2800 {
2801 SVfrQuestionNode *pNode;
2802
2803 if (Name == NULL) {
2804 return VFR_RETURN_FATAL_ERROR;
2805 }
2806
2807 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2808 if (strcmp (pNode->mName, Name) == 0) {
2809 return VFR_RETURN_SUCCESS;
2810 }
2811 }
2812
2813 return VFR_RETURN_UNDEFINED;
2814 }
2815
2816 BOOLEAN VfrCompatibleMode = FALSE;
2817
2818 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
2819
2820