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