]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
Sync basetools' source and binary files with r1707 of the basetools project.
[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
6 All rights reserved. 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 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 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, 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 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 ("UINT8", &pYearField->mFieldType);
748 pYearField->mOffset = 0;
749 pYearField->mNext = pMonthField;
750 pYearField->mArrayNum = 0;
751
752 strcpy (pMonthField->mFieldName, "Month");
753 GetDataType ("UINT8", &pMonthField->mFieldType);
754 pMonthField->mOffset = 1;
755 pMonthField->mNext = pDayField;
756 pMonthField->mArrayNum = 0;
757
758 strcpy (pDayField->mFieldName, "Day");
759 GetDataType ("UINT8", &pDayField->mFieldType);
760 pDayField->mOffset = 2;
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 ("UINT8", &pHoursField->mFieldType);
772 pHoursField->mOffset = 0;
773 pHoursField->mNext = pMinutesField;
774 pHoursField->mArrayNum = 0;
775
776 strcpy (pMinutesField->mFieldName, "Minutes");
777 GetDataType ("UINT8", &pMinutesField->mFieldType);
778 pMinutesField->mOffset = 1;
779 pMinutesField->mNext = pSecondsField;
780 pMinutesField->mArrayNum = 0;
781
782 strcpy (pSecondsField->mFieldName, "Seconds");
783 GetDataType ("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, "", "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, "", "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, "", "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 += 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 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
1390 Index = 0;
1391 } else if (VarType == EFI_VFR_VARSTORE_EFI) {
1392 Index = 1;
1393 } else if (VarType == EFI_VFR_VARSTORE_NAME) {
1394 Index = 2;
1395 }
1396
1397 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1398 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1399 break;
1400 }
1401 }
1402
1403 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1404 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1405 mFreeVarStoreIdBitMap[Index] |= Mask;
1406 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1407 }
1408 }
1409
1410 return EFI_VARSTORE_ID_INVALID;
1411 }
1412
1413 BOOLEAN
1414 CVfrDataStorage::ChekVarStoreIdFree (
1415 IN EFI_VARSTORE_ID VarStoreId
1416 )
1417 {
1418 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1419 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1420
1421 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1422 }
1423
1424 VOID
1425 CVfrDataStorage::MarkVarStoreIdUsed (
1426 IN EFI_VARSTORE_ID VarStoreId
1427 )
1428 {
1429 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1430 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1431
1432 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1433 }
1434
1435 VOID
1436 CVfrDataStorage::MarkVarStoreIdUnused (
1437 IN EFI_VARSTORE_ID VarStoreId
1438 )
1439 {
1440 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1441 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1442
1443 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1444 }
1445
1446 EFI_VFR_RETURN_CODE
1447 CVfrDataStorage::DeclareNameVarStoreBegin (
1448 IN CHAR8 *StoreName
1449 )
1450 {
1451 SVfrVarStorageNode *pNode = NULL;
1452 EFI_VARSTORE_ID VarStoreId;
1453
1454 if (StoreName == NULL) {
1455 return VFR_RETURN_FATAL_ERROR;
1456 }
1457
1458 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1459 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1460 return VFR_RETURN_REDEFINED;
1461 }
1462 }
1463
1464 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1465 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1466 return VFR_RETURN_UNDEFINED;
1467 }
1468
1469 mNewVarStorageNode = pNode;
1470
1471 return VFR_RETURN_SUCCESS;
1472 }
1473
1474 EFI_VFR_RETURN_CODE
1475 CVfrDataStorage::NameTableAddItem (
1476 IN EFI_STRING_ID Item
1477 )
1478 {
1479 EFI_VARSTORE_ID *NewTable, *OldTable;
1480 UINT32 TableSize;
1481
1482 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1483 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1484
1485 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1486 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1487 return VFR_RETURN_OUT_FOR_RESOURCES;
1488 }
1489 memcpy (NewTable, OldTable, TableSize);
1490 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1491 }
1492
1493 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1494 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1495
1496 return VFR_RETURN_SUCCESS;
1497 }
1498
1499 EFI_VFR_RETURN_CODE
1500 CVfrDataStorage::DeclareNameVarStoreEnd (
1501 IN EFI_GUID *Guid
1502 )
1503 {
1504 mNewVarStorageNode->mGuid = *Guid;
1505 mNewVarStorageNode->mNext = mNameVarStoreList;
1506 mNameVarStoreList = mNewVarStorageNode;
1507
1508 mNewVarStorageNode = NULL;
1509
1510 return VFR_RETURN_SUCCESS;
1511 }
1512
1513 EFI_VFR_RETURN_CODE
1514 CVfrDataStorage::DeclareEfiVarStore (
1515 IN CHAR8 *StoreName,
1516 IN EFI_GUID *Guid,
1517 IN EFI_STRING_ID NameStrId,
1518 IN UINT32 VarSize,
1519 IN BOOLEAN Flag
1520 )
1521 {
1522 SVfrVarStorageNode *pNode;
1523 EFI_VARSTORE_ID VarStoreId;
1524
1525 if ((StoreName == NULL) || (Guid == NULL)) {
1526 return VFR_RETURN_FATAL_ERROR;
1527 }
1528
1529 if (VarSize > sizeof (UINT64)) {
1530 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1531 }
1532
1533 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1534 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1535 return VFR_RETURN_REDEFINED;
1536 }
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
1563 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1564 return VFR_RETURN_FATAL_ERROR;
1565 }
1566
1567 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1568
1569 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1570 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1571 } else {
1572 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1573 return VFR_RETURN_VARSTOREID_REDEFINED;
1574 }
1575 MarkVarStoreIdUsed (VarStoreId);
1576 }
1577
1578 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
1579 return VFR_RETURN_OUT_FOR_RESOURCES;
1580 }
1581
1582 pNew->mNext = mBufferVarStoreList;
1583 mBufferVarStoreList = pNew;
1584
1585 if (gCVfrBufferConfig.Register(StoreName) != 0) {
1586 return VFR_RETURN_FATAL_ERROR;
1587 }
1588
1589 return VFR_RETURN_SUCCESS;
1590 }
1591
1592 EFI_VFR_RETURN_CODE
1593 CVfrDataStorage::GetVarStoreId (
1594 IN CHAR8 *StoreName,
1595 OUT EFI_VARSTORE_ID *VarStoreId
1596 )
1597 {
1598 SVfrVarStorageNode *pNode;
1599
1600 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1601 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1602 mCurrVarStorageNode = pNode;
1603 *VarStoreId = pNode->mVarStoreId;
1604 return VFR_RETURN_SUCCESS;
1605 }
1606 }
1607
1608 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1609 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1610 mCurrVarStorageNode = pNode;
1611 *VarStoreId = pNode->mVarStoreId;
1612 return VFR_RETURN_SUCCESS;
1613 }
1614 }
1615
1616 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1617 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1618 mCurrVarStorageNode = pNode;
1619 *VarStoreId = pNode->mVarStoreId;
1620 return VFR_RETURN_SUCCESS;
1621 }
1622 }
1623
1624 mCurrVarStorageNode = NULL;
1625 *VarStoreId = EFI_VARSTORE_ID_INVALID;
1626 return VFR_RETURN_UNDEFINED;
1627 }
1628
1629 EFI_VFR_RETURN_CODE
1630 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1631 IN CHAR8 *StoreName,
1632 OUT CHAR8 **DataTypeName
1633 )
1634 {
1635 SVfrVarStorageNode *pNode;
1636
1637 if ((StoreName == NULL) || (DataTypeName == NULL)) {
1638 return VFR_RETURN_FATAL_ERROR;
1639 }
1640
1641 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1642 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1643 break;
1644 }
1645 }
1646
1647 if (pNode == NULL) {
1648 return VFR_RETURN_UNDEFINED;
1649 }
1650
1651 if (pNode->mStorageInfo.mDataType == NULL) {
1652 return VFR_RETURN_FATAL_ERROR;
1653 }
1654
1655 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
1656 return VFR_RETURN_SUCCESS;
1657 }
1658
1659 EFI_VFR_RETURN_CODE
1660 CVfrDataStorage::GetVarStoreType (
1661 IN CHAR8 *StoreName,
1662 OUT EFI_VFR_VARSTORE_TYPE &VarStoreType
1663 )
1664 {
1665 SVfrVarStorageNode *pNode;
1666
1667 if (StoreName == NULL) {
1668 return VFR_RETURN_FATAL_ERROR;
1669 }
1670
1671 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1672 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1673 VarStoreType = pNode->mVarStoreType;
1674 return VFR_RETURN_SUCCESS;
1675 }
1676 }
1677
1678 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1679 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1680 VarStoreType = pNode->mVarStoreType;
1681 return VFR_RETURN_SUCCESS;
1682 }
1683 }
1684
1685 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1686 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1687 VarStoreType = pNode->mVarStoreType;
1688 return VFR_RETURN_SUCCESS;
1689 }
1690 }
1691
1692 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1693 return VFR_RETURN_UNDEFINED;
1694 }
1695
1696 EFI_VFR_VARSTORE_TYPE
1697 CVfrDataStorage::GetVarStoreType (
1698 IN EFI_VARSTORE_ID VarStoreId
1699 )
1700 {
1701 SVfrVarStorageNode *pNode;
1702 EFI_VFR_VARSTORE_TYPE VarStoreType;
1703
1704 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1705
1706 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1707 return VarStoreType;
1708 }
1709
1710 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1711 if (pNode->mVarStoreId == VarStoreId) {
1712 VarStoreType = pNode->mVarStoreType;
1713 return VarStoreType;
1714 }
1715 }
1716
1717 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1718 if (pNode->mVarStoreId == VarStoreId) {
1719 VarStoreType = pNode->mVarStoreType;
1720 return VarStoreType;
1721 }
1722 }
1723
1724 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1725 if (pNode->mVarStoreId == VarStoreId) {
1726 VarStoreType = pNode->mVarStoreType;
1727 return VarStoreType;
1728 }
1729 }
1730
1731 return VarStoreType;
1732 }
1733
1734 EFI_VFR_RETURN_CODE
1735 CVfrDataStorage::GetVarStoreName (
1736 IN EFI_VARSTORE_ID VarStoreId,
1737 OUT CHAR8 **VarStoreName
1738 )
1739 {
1740 SVfrVarStorageNode *pNode;
1741
1742 if (VarStoreName == NULL) {
1743 return VFR_RETURN_FATAL_ERROR;
1744 }
1745
1746 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1747 if (pNode->mVarStoreId == VarStoreId) {
1748 *VarStoreName = pNode->mVarStoreName;
1749 return VFR_RETURN_SUCCESS;
1750 }
1751 }
1752
1753 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1754 if (pNode->mVarStoreId == VarStoreId) {
1755 *VarStoreName = pNode->mVarStoreName;
1756 return VFR_RETURN_SUCCESS;
1757 }
1758 }
1759
1760 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1761 if (pNode->mVarStoreId == VarStoreId) {
1762 *VarStoreName = pNode->mVarStoreName;
1763 return VFR_RETURN_SUCCESS;
1764 }
1765 }
1766
1767 *VarStoreName = NULL;
1768 return VFR_RETURN_UNDEFINED;
1769 }
1770
1771 EFI_VFR_RETURN_CODE
1772 CVfrDataStorage::GetEfiVarStoreInfo (
1773 IN OUT EFI_VARSTORE_INFO *Info
1774 )
1775 {
1776 if (Info == NULL) {
1777 return VFR_RETURN_FATAL_ERROR;
1778 }
1779
1780 if (mCurrVarStorageNode == NULL) {
1781 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
1782 }
1783
1784 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
1785 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
1786 switch (Info->mVarTotalSize) {
1787 case 1:
1788 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
1789 break;
1790 case 2:
1791 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
1792 break;
1793 case 4:
1794 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
1795 break;
1796 case 8:
1797 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
1798 break;
1799 default :
1800 return VFR_RETURN_FATAL_ERROR;
1801 }
1802
1803 return VFR_RETURN_SUCCESS;
1804 }
1805
1806 EFI_VFR_RETURN_CODE
1807 CVfrDataStorage::GetNameVarStoreInfo (
1808 OUT EFI_VARSTORE_INFO *Info,
1809 IN UINT32 Index
1810 )
1811 {
1812 if (Info == NULL) {
1813 return VFR_RETURN_FATAL_ERROR;
1814 }
1815
1816 if (mCurrVarStorageNode == NULL) {
1817 return VFR_RETURN_GET_NVVARSTORE_ERROR;
1818 }
1819
1820 //
1821 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
1822 //
1823 if (VfrCompatibleMode) {
1824 if (Index == 0) {
1825 return VFR_RETURN_ERROR_ARRARY_NUM;
1826 }
1827 Index --;
1828 }
1829
1830 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
1831
1832 return VFR_RETURN_SUCCESS;
1833 }
1834
1835 EFI_VFR_RETURN_CODE
1836 CVfrDataStorage::BufferVarStoreRequestElementAdd (
1837 IN CHAR8 *StoreName,
1838 IN EFI_VARSTORE_INFO &Info
1839 )
1840 {
1841 CHAR8 NewReqElt[128] = {'\0',};
1842 CHAR8 *OldReqElt = NULL;
1843 SVfrVarStorageNode *pNode = NULL;
1844 EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;
1845
1846 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1847 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
1848 break;
1849 }
1850 }
1851
1852 if (pNode == NULL) {
1853 return VFR_RETURN_UNDEFINED;
1854 }
1855
1856 gCVfrBufferConfig.Open ();
1857 Value.u8 = 0;
1858 if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
1859 return VFR_RETURN_FATAL_ERROR;
1860 }
1861 gCVfrBufferConfig.Close ();
1862
1863 return VFR_RETURN_SUCCESS;
1864 }
1865
1866 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
1867 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
1868 IN CHAR8 *RefName,
1869 IN EFI_STRING_ID DefaultStoreNameId,
1870 IN UINT16 DefaultId
1871 )
1872 {
1873 mObjBinAddr = ObjBinAddr;
1874
1875 if (RefName != NULL) {
1876 mRefName = new CHAR8[strlen (RefName) + 1];
1877 strcpy (mRefName, RefName);
1878 } else {
1879 mRefName = NULL;
1880 }
1881
1882 mNext = NULL;
1883 mDefaultId = DefaultId;
1884 mDefaultStoreNameId = DefaultStoreNameId;
1885 }
1886
1887 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
1888 VOID
1889 )
1890 {
1891 if (mRefName != NULL) {
1892 delete mRefName;
1893 }
1894 }
1895
1896 CVfrDefaultStore::CVfrDefaultStore (
1897 VOID
1898 )
1899 {
1900 mDefaultStoreList = NULL;
1901 }
1902
1903 CVfrDefaultStore::~CVfrDefaultStore (
1904 VOID
1905 )
1906 {
1907 SVfrDefaultStoreNode *pTmp = NULL;
1908
1909 while (mDefaultStoreList != NULL) {
1910 pTmp = mDefaultStoreList;
1911 mDefaultStoreList = mDefaultStoreList->mNext;
1912 delete pTmp;
1913 }
1914 }
1915
1916 EFI_VFR_RETURN_CODE
1917 CVfrDefaultStore::RegisterDefaultStore (
1918 IN CHAR8 *ObjBinAddr,
1919 IN CHAR8 *RefName,
1920 IN EFI_STRING_ID DefaultStoreNameId,
1921 IN UINT16 DefaultId
1922 )
1923 {
1924 SVfrDefaultStoreNode *pNode = NULL;
1925
1926 if (RefName == NULL) {
1927 return VFR_RETURN_FATAL_ERROR;
1928 }
1929
1930 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1931 if (strcmp (pNode->mRefName, RefName) == 0) {
1932 return VFR_RETURN_REDEFINED;
1933 }
1934 }
1935
1936 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
1937 return VFR_RETURN_OUT_FOR_RESOURCES;
1938 }
1939
1940 pNode->mNext = mDefaultStoreList;
1941 mDefaultStoreList = pNode;
1942
1943 return VFR_RETURN_SUCCESS;
1944 }
1945
1946 /*
1947 * assign new reference name or new default store name id only if
1948 * the original is invalid
1949 */
1950 EFI_VFR_RETURN_CODE
1951 CVfrDefaultStore::ReRegisterDefaultStoreById (
1952 IN UINT16 DefaultId,
1953 IN CHAR8 *RefName,
1954 IN EFI_STRING_ID DefaultStoreNameId
1955 )
1956 {
1957 SVfrDefaultStoreNode *pNode = NULL;
1958
1959 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1960 if (pNode->mDefaultId == DefaultId) {
1961 break;
1962 }
1963 }
1964
1965 if (pNode == NULL) {
1966 return VFR_RETURN_UNDEFINED;
1967 } else {
1968 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
1969 pNode->mDefaultStoreNameId = DefaultStoreNameId;
1970 if (pNode->mObjBinAddr != NULL) {
1971 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
1972 }
1973 } else {
1974 return VFR_RETURN_REDEFINED;
1975 }
1976
1977 if (RefName != NULL) {
1978 delete pNode->mRefName;
1979 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
1980 if (pNode->mRefName != NULL) {
1981 strcpy (pNode->mRefName, RefName);
1982 }
1983 }
1984 }
1985
1986 return VFR_RETURN_SUCCESS;
1987 }
1988
1989 BOOLEAN
1990 CVfrDefaultStore::DefaultIdRegistered (
1991 IN UINT16 DefaultId
1992 )
1993 {
1994 SVfrDefaultStoreNode *pNode = NULL;
1995
1996 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
1997 if (pNode->mDefaultId == DefaultId) {
1998 return TRUE;
1999 }
2000 }
2001
2002 return FALSE;
2003 }
2004
2005 EFI_VFR_RETURN_CODE
2006 CVfrDefaultStore::GetDefaultId (
2007 IN CHAR8 *RefName,
2008 OUT UINT16 *DefaultId
2009 )
2010 {
2011 SVfrDefaultStoreNode *pTmp = NULL;
2012
2013 if (DefaultId == NULL) {
2014 return VFR_RETURN_FATAL_ERROR;
2015 }
2016
2017 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2018 if (strcmp (pTmp->mRefName, RefName) == 0) {
2019 *DefaultId = pTmp->mDefaultId;
2020 return VFR_RETURN_SUCCESS;
2021 }
2022 }
2023
2024 return VFR_RETURN_UNDEFINED;
2025 }
2026
2027 STATIC
2028 EFI_VFR_RETURN_CODE
2029 AltCfgItemPrintToBuffer (
2030 IN CHAR8 *NewAltCfg,
2031 IN EFI_VARSTORE_INFO Info,
2032 IN UINT8 Type,
2033 IN EFI_IFR_TYPE_VALUE Value
2034 )
2035 {
2036 UINT32 Index;
2037 UINT8 *BufChar = NULL;
2038 UINT32 Count = 0;
2039
2040 if (NewAltCfg != NULL) {
2041 Count = sprintf (
2042 NewAltCfg,
2043 "&OFFSET=%x&WIDTH=%x&VALUE=",
2044 Info.mInfo.mVarOffset,
2045 Info.mVarTotalSize
2046 );
2047 NewAltCfg += Count;
2048
2049 switch (Type) {
2050 case EFI_IFR_TYPE_NUM_SIZE_8 :
2051 Count = sprintf (NewAltCfg, "%x", Value.u8);
2052 NewAltCfg += Count;
2053 break;
2054 case EFI_IFR_TYPE_NUM_SIZE_16 :
2055 Count = sprintf (NewAltCfg, "%x", Value.u16);
2056 NewAltCfg += Count;
2057 break;
2058 case EFI_IFR_TYPE_NUM_SIZE_32 :
2059 Count = sprintf (NewAltCfg, "%x", Value.u32);
2060 NewAltCfg += Count;
2061 break;
2062 case EFI_IFR_TYPE_NUM_SIZE_64 :
2063 Count = sprintf (NewAltCfg, "%x", Value.u64);
2064 NewAltCfg += Count;
2065 break;
2066 case EFI_IFR_TYPE_BOOLEAN :
2067 Count = sprintf (NewAltCfg, "%x", Value.b);
2068 NewAltCfg += Count;
2069 break;
2070 case EFI_IFR_TYPE_TIME :
2071 #if 1
2072 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));
2073 NewAltCfg += Count;
2074 #else
2075 BufChar = (UINT8 *)&Value.time;
2076 for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {
2077 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
2078 NewAltCfg += Count;
2079 }
2080 #endif
2081 break;
2082 case EFI_IFR_TYPE_DATE :
2083 #if 1
2084 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));
2085 NewAltCfg += Count;
2086 #else
2087 BufChar = (UINT8 *)&Value.date;
2088 for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {
2089 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
2090 NewAltCfg += Count;
2091 }
2092 #endif
2093 break;
2094 case EFI_IFR_TYPE_STRING :
2095 Count = sprintf (NewAltCfg, "%x", Value.string);
2096 NewAltCfg += Count;
2097 break;
2098 case EFI_IFR_TYPE_OTHER :
2099 return VFR_RETURN_UNSUPPORTED;
2100 }
2101 }
2102
2103 return VFR_RETURN_FATAL_ERROR;
2104 }
2105
2106 EFI_VFR_RETURN_CODE
2107 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2108 IN EFI_VARSTORE_ID DefaultId,
2109 IN EFI_VARSTORE_INFO &Info,
2110 IN CHAR8 *VarStoreName,
2111 IN UINT8 Type,
2112 IN EFI_IFR_TYPE_VALUE Value
2113 )
2114 {
2115 SVfrDefaultStoreNode *pNode = NULL;
2116 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2117 INTN Returnvalue = 0;
2118
2119 if (VarStoreName == NULL) {
2120 return VFR_RETURN_FATAL_ERROR;
2121 }
2122
2123 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2124 if (pNode->mDefaultId == DefaultId) {
2125 break;
2126 }
2127 }
2128
2129 if (pNode == NULL) {
2130 return VFR_RETURN_UNDEFINED;
2131 }
2132
2133 gCVfrBufferConfig.Open ();
2134
2135 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2136 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {
2137 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2138 goto WriteError;
2139 }
2140 }
2141
2142 gCVfrBufferConfig.Close ();
2143
2144 return VFR_RETURN_SUCCESS;
2145
2146 WriteError:
2147 gCVfrBufferConfig.Close ();
2148 return (EFI_VFR_RETURN_CODE)Returnvalue;
2149 }
2150
2151 SVfrRuleNode::SVfrRuleNode (
2152 IN CHAR8 *RuleName,
2153 IN UINT8 RuleId
2154 )
2155 {
2156 if (RuleName != NULL) {
2157 mRuleName = new CHAR8[strlen (RuleName) + 1];
2158 strcpy (mRuleName, RuleName);
2159 } else {
2160 mRuleName = NULL;
2161 }
2162
2163 mNext = NULL;
2164 mRuleId = RuleId;
2165 }
2166
2167 SVfrRuleNode::~SVfrRuleNode (
2168 VOID
2169 )
2170 {
2171 if (mRuleName != NULL) {
2172 delete mRuleName;
2173 }
2174 }
2175
2176 CVfrRulesDB::CVfrRulesDB ()
2177 {
2178 mRuleList = NULL;
2179 mFreeRuleId = EFI_VARSTORE_ID_START;
2180 }
2181
2182 CVfrRulesDB::~CVfrRulesDB ()
2183 {
2184 SVfrRuleNode *pNode;
2185
2186 while(mRuleList != NULL) {
2187 pNode = mRuleList;
2188 mRuleList = mRuleList->mNext;
2189 delete pNode;
2190 }
2191 }
2192
2193 VOID
2194 CVfrRulesDB::RegisterRule (
2195 IN CHAR8 *RuleName
2196 )
2197 {
2198 SVfrRuleNode *pNew;
2199
2200 if (RuleName == NULL) {
2201 return ;
2202 }
2203
2204 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2205 return ;
2206 }
2207
2208 mFreeRuleId++;
2209
2210 pNew->mNext = mRuleList;
2211 mRuleList = pNew;
2212 }
2213
2214 UINT8
2215 CVfrRulesDB::GetRuleId (
2216 IN CHAR8 *RuleName
2217 )
2218 {
2219 SVfrRuleNode *pNode;
2220
2221 if (RuleName == NULL) {
2222 return EFI_RULE_ID_INVALID;
2223 }
2224
2225 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2226 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2227 return pNode->mRuleId;
2228 }
2229 }
2230
2231 return EFI_RULE_ID_INVALID;
2232 }
2233
2234 CVfrRulesDB gCVfrRulesDB;
2235
2236 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2237 VOID
2238 )
2239 {
2240 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2241 mInfo.mVarName = EFI_STRING_ID_INVALID;
2242 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2243 mVarType = EFI_IFR_TYPE_OTHER;
2244 mVarTotalSize = 0;
2245 }
2246
2247 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2248 IN EFI_VARSTORE_INFO &Info
2249 )
2250 {
2251 mVarStoreId = Info.mVarStoreId;
2252 mInfo.mVarName = Info.mInfo.mVarName;
2253 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2254 mVarType = Info.mVarType;
2255 mVarTotalSize = Info.mVarTotalSize;
2256 }
2257
2258 BOOLEAN
2259 EFI_VARSTORE_INFO::operator == (
2260 IN EFI_VARSTORE_INFO *Info
2261 )
2262 {
2263 if ((mVarStoreId == Info->mVarStoreId) &&
2264 (mInfo.mVarName == Info->mInfo.mVarName) &&
2265 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2266 (mVarType == Info->mVarType) &&
2267 (mVarTotalSize == Info->mVarTotalSize)) {
2268 return TRUE;
2269 }
2270
2271 return FALSE;
2272 }
2273
2274 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2275
2276 EFI_QUESTION_ID
2277 CVfrQuestionDB::GetFreeQuestionId (
2278 VOID
2279 )
2280 {
2281 UINT32 Index, Mask, Offset;
2282
2283 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2284 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2285 break;
2286 }
2287 }
2288
2289 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2290 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2291 mFreeQIdBitMap[Index] |= Mask;
2292 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2293 }
2294 }
2295
2296 return EFI_QUESTION_ID_INVALID;
2297 }
2298
2299 BOOLEAN
2300 CVfrQuestionDB::ChekQuestionIdFree (
2301 IN EFI_QUESTION_ID QId
2302 )
2303 {
2304 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2305 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2306
2307 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2308 }
2309
2310 VOID
2311 CVfrQuestionDB::MarkQuestionIdUsed (
2312 IN EFI_QUESTION_ID QId
2313 )
2314 {
2315 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2316 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2317
2318 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2319 }
2320
2321 VOID
2322 CVfrQuestionDB::MarkQuestionIdUnused (
2323 IN EFI_QUESTION_ID QId
2324 )
2325 {
2326 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2327 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2328
2329 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2330 }
2331
2332 SVfrQuestionNode::SVfrQuestionNode (
2333 IN CHAR8 *Name,
2334 IN CHAR8 *VarIdStr,
2335 IN UINT32 BitMask
2336 )
2337 {
2338 mName = NULL;
2339 mVarIdStr = NULL;
2340 mQuestionId = EFI_QUESTION_ID_INVALID;
2341 mBitMask = BitMask;
2342 mNext = NULL;
2343
2344 if (Name == NULL) {
2345 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2346 strcpy (mName, "$DEFAULT");
2347 } else {
2348 mName = new CHAR8[strlen (Name) + 1];
2349 strcpy (mName, Name);
2350 }
2351
2352 if (VarIdStr != NULL) {
2353 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2354 strcpy (mVarIdStr, VarIdStr);
2355 } else {
2356 mVarIdStr = new CHAR8[strlen ("$") + 1];
2357 strcpy (mVarIdStr, "$");
2358 }
2359 }
2360
2361 SVfrQuestionNode::~SVfrQuestionNode (
2362 VOID
2363 )
2364 {
2365 if (mName != NULL) {
2366 delete mName;
2367 }
2368
2369 if (mVarIdStr != NULL) {
2370 delete mVarIdStr;
2371 }
2372 }
2373
2374 CVfrQuestionDB::CVfrQuestionDB ()
2375 {
2376 UINT32 Index;
2377
2378 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2379 mFreeQIdBitMap[Index] = 0;
2380 }
2381
2382 // Question ID 0 is reserved.
2383 mFreeQIdBitMap[0] = 0x80000000;
2384 mQuestionList = NULL;
2385 }
2386
2387 CVfrQuestionDB::~CVfrQuestionDB ()
2388 {
2389 SVfrQuestionNode *pNode;
2390
2391 while (mQuestionList != NULL) {
2392 pNode = mQuestionList;
2393 mQuestionList = mQuestionList->mNext;
2394 delete pNode;
2395 }
2396 }
2397
2398 //
2399 // Reset to init state
2400 //
2401 VOID
2402 CVfrQuestionDB::ResetInit(
2403 IN VOID
2404 )
2405 {
2406 UINT32 Index;
2407 SVfrQuestionNode *pNode;
2408
2409 while (mQuestionList != NULL) {
2410 pNode = mQuestionList;
2411 mQuestionList = mQuestionList->mNext;
2412 delete pNode;
2413 }
2414
2415 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2416 mFreeQIdBitMap[Index] = 0;
2417 }
2418
2419 // Question ID 0 is reserved.
2420 mFreeQIdBitMap[0] = 0x80000000;
2421 mQuestionList = NULL;
2422 }
2423
2424 VOID
2425 CVfrQuestionDB::PrintAllQuestion (
2426 VOID
2427 )
2428 {
2429 SVfrQuestionNode *pNode = NULL;
2430
2431 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2432 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2433 }
2434 }
2435
2436 EFI_VFR_RETURN_CODE
2437 CVfrQuestionDB::RegisterQuestion (
2438 IN CHAR8 *Name,
2439 IN CHAR8 *VarIdStr,
2440 IN OUT EFI_QUESTION_ID &QuestionId
2441 )
2442 {
2443 SVfrQuestionNode *pNode = NULL;
2444
2445 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2446 return VFR_RETURN_REDEFINED;
2447 }
2448
2449 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2450 return VFR_RETURN_OUT_FOR_RESOURCES;
2451 }
2452
2453 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2454 QuestionId = GetFreeQuestionId ();
2455 } else {
2456 //
2457 // For Framework Vfr, don't check question ID conflict.
2458 //
2459 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
2460 delete pNode;
2461 return VFR_RETURN_QUESTIONID_REDEFINED;
2462 }
2463 MarkQuestionIdUsed (QuestionId);
2464 }
2465 pNode->mQuestionId = QuestionId;
2466
2467 pNode->mNext = mQuestionList;
2468 mQuestionList = pNode;
2469
2470 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2471
2472 return VFR_RETURN_SUCCESS;
2473 }
2474
2475 VOID
2476 CVfrQuestionDB::RegisterOldDateQuestion (
2477 IN CHAR8 *YearVarId,
2478 IN CHAR8 *MonthVarId,
2479 IN CHAR8 *DayVarId,
2480 IN OUT EFI_QUESTION_ID &QuestionId
2481 )
2482 {
2483 SVfrQuestionNode *pNode[3] = {NULL, };
2484 UINT32 Index;
2485
2486 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2487 return;
2488 }
2489
2490 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2491 goto Err;
2492 }
2493 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2494 goto Err;
2495 }
2496 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, 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]->mNext = pNode[1];
2513 pNode[1]->mNext = pNode[2];
2514 pNode[2]->mNext = mQuestionList;
2515 mQuestionList = pNode[0];
2516
2517 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2518 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2519 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2520
2521 return;
2522
2523 Err:
2524 for (Index = 0; Index < 3; Index++) {
2525 if (pNode[Index] != NULL) {
2526 delete pNode[Index];
2527 }
2528 }
2529 QuestionId = EFI_QUESTION_ID_INVALID;
2530 }
2531
2532 VOID
2533 CVfrQuestionDB::RegisterNewDateQuestion (
2534 IN CHAR8 *Name,
2535 IN CHAR8 *BaseVarId,
2536 IN OUT EFI_QUESTION_ID &QuestionId
2537 )
2538 {
2539 SVfrQuestionNode *pNode[3] = {NULL, };
2540 UINT32 Len;
2541 CHAR8 *VarIdStr[3] = {NULL, };
2542 CHAR8 Index;
2543
2544 if (BaseVarId == NULL) {
2545 return;
2546 }
2547
2548 Len = strlen (BaseVarId);
2549
2550 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2551 if (VarIdStr[0] != NULL) {
2552 strcpy (VarIdStr[0], BaseVarId);
2553 strcat (VarIdStr[0], ".Year");
2554 }
2555 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2556 if (VarIdStr[1] != NULL) {
2557 strcpy (VarIdStr[1], BaseVarId);
2558 strcat (VarIdStr[1], ".Month");
2559 }
2560 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2561 if (VarIdStr[2] != NULL) {
2562 strcpy (VarIdStr[2], BaseVarId);
2563 strcat (VarIdStr[2], ".Day");
2564 }
2565
2566 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2567 goto Err;
2568 }
2569 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2570 goto Err;
2571 }
2572 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2573 goto Err;
2574 }
2575
2576 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2577 QuestionId = GetFreeQuestionId ();
2578 } else {
2579 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2580 goto Err;
2581 }
2582 MarkQuestionIdUsed (QuestionId);
2583 }
2584
2585 pNode[0]->mQuestionId = QuestionId;
2586 pNode[1]->mQuestionId = QuestionId;
2587 pNode[2]->mQuestionId = QuestionId;
2588 pNode[0]->mNext = pNode[1];
2589 pNode[1]->mNext = pNode[2];
2590 pNode[2]->mNext = mQuestionList;
2591 mQuestionList = pNode[0];
2592
2593 for (Index = 0; Index < 3; Index++) {
2594 if (VarIdStr[Index] != NULL) {
2595 delete VarIdStr[Index];
2596 }
2597 }
2598
2599 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2600 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2601 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2602
2603 return;
2604
2605 Err:
2606 for (Index = 0; Index < 3; Index++) {
2607 if (pNode[Index] != NULL) {
2608 delete pNode[Index];
2609 }
2610
2611 if (VarIdStr[Index] != NULL) {
2612 delete VarIdStr[Index];
2613 }
2614 }
2615 }
2616
2617 VOID
2618 CVfrQuestionDB::RegisterOldTimeQuestion (
2619 IN CHAR8 *HourVarId,
2620 IN CHAR8 *MinuteVarId,
2621 IN CHAR8 *SecondVarId,
2622 IN OUT EFI_QUESTION_ID &QuestionId
2623 )
2624 {
2625 SVfrQuestionNode *pNode[3] = {NULL, };
2626 UINT32 Index;
2627
2628 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
2629 return;
2630 }
2631
2632 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
2633 goto Err;
2634 }
2635 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
2636 goto Err;
2637 }
2638 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
2639 goto Err;
2640 }
2641
2642 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2643 QuestionId = GetFreeQuestionId ();
2644 } else {
2645 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2646 goto Err;
2647 }
2648 MarkQuestionIdUsed (QuestionId);
2649 }
2650
2651 pNode[0]->mQuestionId = QuestionId;
2652 pNode[1]->mQuestionId = QuestionId;
2653 pNode[2]->mQuestionId = QuestionId;
2654 pNode[0]->mNext = pNode[1];
2655 pNode[1]->mNext = pNode[2];
2656 pNode[2]->mNext = mQuestionList;
2657 mQuestionList = pNode[0];
2658
2659 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2660 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2661 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2662
2663 return;
2664
2665 Err:
2666 for (Index = 0; Index < 3; Index++) {
2667 if (pNode[Index] != NULL) {
2668 delete pNode[Index];
2669 }
2670 }
2671 QuestionId = EFI_QUESTION_ID_INVALID;
2672 }
2673
2674 VOID
2675 CVfrQuestionDB::RegisterNewTimeQuestion (
2676 IN CHAR8 *Name,
2677 IN CHAR8 *BaseVarId,
2678 IN OUT EFI_QUESTION_ID &QuestionId
2679 )
2680 {
2681 SVfrQuestionNode *pNode[3] = {NULL, };
2682 UINT32 Len;
2683 CHAR8 *VarIdStr[3] = {NULL, };
2684 CHAR8 Index;
2685
2686 if (BaseVarId == NULL) {
2687 return;
2688 }
2689
2690 Len = strlen (BaseVarId);
2691
2692 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2693 if (VarIdStr[0] != NULL) {
2694 strcpy (VarIdStr[0], BaseVarId);
2695 strcat (VarIdStr[0], ".Hour");
2696 }
2697 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2698 if (VarIdStr[1] != NULL) {
2699 strcpy (VarIdStr[1], BaseVarId);
2700 strcat (VarIdStr[1], ".Minute");
2701 }
2702 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2703 if (VarIdStr[2] != NULL) {
2704 strcpy (VarIdStr[2], BaseVarId);
2705 strcat (VarIdStr[2], ".Second");
2706 }
2707
2708 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
2709 goto Err;
2710 }
2711 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
2712 goto Err;
2713 }
2714 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
2715 goto Err;
2716 }
2717
2718 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2719 QuestionId = GetFreeQuestionId ();
2720 } else {
2721 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2722 goto Err;
2723 }
2724 MarkQuestionIdUsed (QuestionId);
2725 }
2726
2727 pNode[0]->mQuestionId = QuestionId;
2728 pNode[1]->mQuestionId = QuestionId;
2729 pNode[2]->mQuestionId = QuestionId;
2730 pNode[0]->mNext = pNode[1];
2731 pNode[1]->mNext = pNode[2];
2732 pNode[2]->mNext = mQuestionList;
2733 mQuestionList = pNode[0];
2734
2735 for (Index = 0; Index < 3; Index++) {
2736 if (VarIdStr[Index] != NULL) {
2737 delete VarIdStr[Index];
2738 }
2739 }
2740
2741 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2742 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2743 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2744
2745 return;
2746
2747 Err:
2748 for (Index = 0; Index < 3; Index++) {
2749 if (pNode[Index] != NULL) {
2750 delete pNode[Index];
2751 }
2752
2753 if (VarIdStr[Index] != NULL) {
2754 delete VarIdStr[Index];
2755 }
2756 }
2757 }
2758
2759 EFI_VFR_RETURN_CODE
2760 CVfrQuestionDB::UpdateQuestionId (
2761 IN EFI_QUESTION_ID QId,
2762 IN EFI_QUESTION_ID NewQId
2763 )
2764 {
2765 SVfrQuestionNode *pNode = NULL;
2766
2767 if (QId == NewQId) {
2768 // don't update
2769 return VFR_RETURN_SUCCESS;
2770 }
2771
2772 //
2773 // For Framework Vfr, don't check question ID conflict.
2774 //
2775 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
2776 return VFR_RETURN_REDEFINED;
2777 }
2778
2779 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2780 if (pNode->mQuestionId == QId) {
2781 break;
2782 }
2783 }
2784
2785 if (pNode == NULL) {
2786 return VFR_RETURN_UNDEFINED;
2787 }
2788
2789 MarkQuestionIdUnused (QId);
2790 pNode->mQuestionId = NewQId;
2791 MarkQuestionIdUsed (NewQId);
2792
2793 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
2794
2795 return VFR_RETURN_SUCCESS;
2796 }
2797
2798 VOID
2799 CVfrQuestionDB::GetQuestionId (
2800 IN CHAR8 *Name,
2801 IN CHAR8 *VarIdStr,
2802 OUT EFI_QUESTION_ID &QuestionId,
2803 OUT UINT32 &BitMask
2804 )
2805 {
2806 SVfrQuestionNode *pNode;
2807
2808 QuestionId = EFI_QUESTION_ID_INVALID;
2809 BitMask = 0x00000000;
2810
2811 if ((Name == NULL) && (VarIdStr == NULL)) {
2812 return ;
2813 }
2814
2815 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2816 if (Name != NULL) {
2817 if (strcmp (pNode->mName, Name) != 0) {
2818 continue;
2819 }
2820 }
2821
2822 if (VarIdStr != NULL) {
2823 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
2824 continue;
2825 }
2826 }
2827
2828 QuestionId = pNode->mQuestionId;
2829 BitMask = pNode->mBitMask;
2830 break;
2831 }
2832
2833 return ;
2834 }
2835
2836 EFI_VFR_RETURN_CODE
2837 CVfrQuestionDB::FindQuestion (
2838 IN EFI_QUESTION_ID QuestionId
2839 )
2840 {
2841 SVfrQuestionNode *pNode;
2842
2843 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2844 return VFR_RETURN_INVALID_PARAMETER;
2845 }
2846
2847 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2848 if (pNode->mQuestionId == QuestionId) {
2849 return VFR_RETURN_SUCCESS;
2850 }
2851 }
2852
2853 return VFR_RETURN_UNDEFINED;
2854 }
2855
2856 EFI_VFR_RETURN_CODE
2857 CVfrQuestionDB::FindQuestion (
2858 IN CHAR8 *Name
2859 )
2860 {
2861 SVfrQuestionNode *pNode;
2862
2863 if (Name == NULL) {
2864 return VFR_RETURN_FATAL_ERROR;
2865 }
2866
2867 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2868 if (strcmp (pNode->mName, Name) == 0) {
2869 return VFR_RETURN_SUCCESS;
2870 }
2871 }
2872
2873 return VFR_RETURN_UNDEFINED;
2874 }
2875
2876 BOOLEAN VfrCompatibleMode = FALSE;
2877
2878 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
2879