]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools/VfrCompile: Add checks for array access
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
1 /** @file
2
3 Vfr common library functions.
4
5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "stdio.h"
17 #include "stdlib.h"
18 #include "CommonLib.h"
19 #include "VfrUtilityLib.h"
20 #include "VfrFormPkg.h"
21
22 VOID
23 CVfrBinaryOutput::WriteLine (
24 IN FILE *pFile,
25 IN UINT32 LineBytes,
26 IN CONST CHAR8 *LineHeader,
27 IN CHAR8 *BlkBuf,
28 IN UINT32 BlkSize
29 )
30 {
31 UINT32 Index;
32
33 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
34 return;
35 }
36
37 for (Index = 0; Index < BlkSize; Index++) {
38 if ((Index % LineBytes) == 0) {
39 fprintf (pFile, "\n%s", LineHeader);
40 }
41 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
42 }
43 }
44
45 VOID
46 CVfrBinaryOutput::WriteEnd (
47 IN FILE *pFile,
48 IN UINT32 LineBytes,
49 IN CONST CHAR8 *LineHeader,
50 IN CHAR8 *BlkBuf,
51 IN UINT32 BlkSize
52 )
53 {
54 UINT32 Index;
55
56 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
57 return;
58 }
59
60 for (Index = 0; Index < BlkSize - 1; Index++) {
61 if ((Index % LineBytes) == 0) {
62 fprintf (pFile, "\n%s", LineHeader);
63 }
64 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
65 }
66
67 if ((Index % LineBytes) == 0) {
68 fprintf (pFile, "\n%s", LineHeader);
69 }
70 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
71 }
72
73 SConfigInfo::SConfigInfo (
74 IN UINT8 Type,
75 IN UINT16 Offset,
76 IN UINT32 Width,
77 IN EFI_IFR_TYPE_VALUE Value
78 )
79 {
80 mNext = NULL;
81 mOffset = Offset;
82 mWidth = (UINT16)Width;
83 mValue = new UINT8[mWidth];
84 if (mValue == NULL) {
85 return;
86 }
87
88 switch (Type) {
89 case EFI_IFR_TYPE_NUM_SIZE_8 :
90 memcpy (mValue, &Value.u8, mWidth);
91 break;
92 case EFI_IFR_TYPE_NUM_SIZE_16 :
93 memcpy (mValue, &Value.u16, mWidth);
94 break;
95 case EFI_IFR_TYPE_NUM_SIZE_32 :
96 memcpy (mValue, &Value.u32, mWidth);
97 break;
98 case EFI_IFR_TYPE_NUM_SIZE_64 :
99 memcpy (mValue, &Value.u64, mWidth);
100 break;
101 case EFI_IFR_TYPE_BOOLEAN :
102 memcpy (mValue, &Value.b, mWidth);
103 break;
104 case EFI_IFR_TYPE_TIME :
105 memcpy (mValue, &Value.time, mWidth);
106 break;
107 case EFI_IFR_TYPE_DATE :
108 memcpy (mValue, &Value.date, mWidth);
109 break;
110 case EFI_IFR_TYPE_STRING :
111 memcpy (mValue, &Value.string, mWidth);
112 break;
113 case EFI_IFR_TYPE_BUFFER :
114 memcpy (mValue, &Value.u8, mWidth);
115 break;
116
117 case EFI_IFR_TYPE_OTHER :
118 return;
119 }
120 }
121
122 SConfigInfo::~SConfigInfo (
123 VOID
124 )
125 {
126 BUFFER_SAFE_FREE (mValue);
127 }
128
129 SConfigItem::SConfigItem (
130 IN CHAR8 *Name,
131 IN EFI_GUID *Guid,
132 IN CHAR8 *Id
133 )
134 {
135 mName = NULL;
136 mGuid = NULL;
137 mId = NULL;
138 mInfoStrList = NULL;
139 mNext = NULL;
140
141 if (Name != NULL) {
142 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
143 strcpy (mName, Name);
144 }
145 }
146
147 if (Guid != NULL) {
148 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
149 memcpy (mGuid, Guid, sizeof (EFI_GUID));
150 }
151 }
152
153 if (Id != NULL) {
154 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
155 strcpy (mId, Id);
156 }
157 }
158 }
159
160 SConfigItem::SConfigItem (
161 IN CHAR8 *Name,
162 IN EFI_GUID *Guid,
163 IN CHAR8 *Id,
164 IN UINT8 Type,
165 IN UINT16 Offset,
166 IN UINT16 Width,
167 IN EFI_IFR_TYPE_VALUE Value
168 )
169 {
170 mName = NULL;
171 mGuid = NULL;
172 mId = NULL;
173 mInfoStrList = NULL;
174 mNext = NULL;
175
176 if (Name != NULL) {
177 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
178 strcpy (mName, Name);
179 }
180 }
181
182 if (Guid != NULL) {
183 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
184 memcpy (mGuid, Guid, sizeof (EFI_GUID));
185 }
186 }
187
188 if (Id != NULL) {
189 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
190 strcpy (mId, Id);
191 }
192 }
193
194 mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
195 }
196
197 SConfigItem::~SConfigItem (
198 VOID
199 )
200 {
201 SConfigInfo *Info;
202
203 BUFFER_SAFE_FREE (mName);
204 BUFFER_SAFE_FREE (mGuid);
205 BUFFER_SAFE_FREE (mId);
206 while (mInfoStrList != NULL) {
207 Info = mInfoStrList;
208 mInfoStrList = mInfoStrList->mNext;
209
210 BUFFER_SAFE_FREE (Info);
211 }
212 }
213
214 UINT8
215 CVfrBufferConfig::Register (
216 IN CHAR8 *Name,
217 IN EFI_GUID *Guid,
218 IN CHAR8 *Id
219 )
220 {
221 SConfigItem *pNew;
222
223 if (Select (Name, Guid) == 0) {
224 return 1;
225 }
226
227 if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {
228 return 2;
229 }
230
231 if (mItemListHead == NULL) {
232 mItemListHead = pNew;
233 mItemListTail = pNew;
234 } else {
235 mItemListTail->mNext = pNew;
236 mItemListTail = pNew;
237 }
238 mItemListPos = pNew;
239
240 return 0;
241 }
242
243 VOID
244 CVfrBufferConfig::Open (
245 VOID
246 )
247 {
248 mItemListPos = mItemListHead;
249 }
250
251 BOOLEAN
252 CVfrBufferConfig::Eof(
253 VOID
254 )
255 {
256 return (mItemListPos == NULL) ? TRUE : FALSE;
257 }
258
259 UINT8
260 CVfrBufferConfig::Select (
261 IN CHAR8 *Name,
262 IN EFI_GUID *Guid,
263 IN CHAR8 *Id
264 )
265 {
266 SConfigItem *p;
267
268 if (Name == NULL || Guid == NULL) {
269 mItemListPos = mItemListHead;
270 return 0;
271 } else {
272 for (p = mItemListHead; p != NULL; p = p->mNext) {
273 if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {
274 continue;
275 }
276
277 if (Id != NULL) {
278 if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
279 continue;
280 }
281 } else if (p->mId != NULL) {
282 continue;
283 }
284
285 mItemListPos = p;
286 return 0;
287 }
288 }
289
290 return 1;
291 }
292
293 UINT8
294 CVfrBufferConfig::Write (
295 IN CONST CHAR8 Mode,
296 IN CHAR8 *Name,
297 IN EFI_GUID *Guid,
298 IN CHAR8 *Id,
299 IN UINT8 Type,
300 IN UINT16 Offset,
301 IN UINT32 Width,
302 IN EFI_IFR_TYPE_VALUE Value
303 )
304 {
305 UINT8 Ret;
306 SConfigItem *pItem;
307 SConfigInfo *pInfo;
308
309 if ((Ret = Select (Name, Guid)) != 0) {
310 return Ret;
311 }
312
313 switch (Mode) {
314 case 'a' : // add
315 if (Select (Name, Guid, Id) != 0) {
316 if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {
317 return 2;
318 }
319 if (mItemListHead == NULL) {
320 mItemListHead = pItem;
321 mItemListTail = pItem;
322 } else {
323 mItemListTail->mNext = pItem;
324 mItemListTail = pItem;
325 }
326 mItemListPos = pItem;
327 } else {
328 // tranverse the list to find out if there's already the value for the same offset
329 for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
330 if (pInfo->mOffset == Offset) {
331 return 0;
332 }
333 }
334 if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
335 return 2;
336 }
337 pInfo->mNext = mItemListPos->mInfoStrList;
338 mItemListPos->mInfoStrList = pInfo;
339 }
340 break;
341
342 case 'd' : // delete
343 if (mItemListHead == mItemListPos) {
344 mItemListHead = mItemListPos->mNext;
345 delete mItemListPos;
346 break;
347 }
348
349 for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
350 ;
351
352 pItem->mNext = mItemListPos->mNext;
353 if (mItemListTail == mItemListPos) {
354 mItemListTail = pItem;
355 }
356 delete mItemListPos;
357 mItemListPos = pItem->mNext;
358 break;
359
360 case 'i' : // set info
361 if (mItemListPos->mId != NULL) {
362 delete mItemListPos->mId;
363 }
364 mItemListPos->mId = NULL;
365 if (Id != NULL) {
366 if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
367 return 2;
368 }
369 strcpy (mItemListPos->mId, Id);
370 }
371 break;
372
373 default :
374 return 1;
375 }
376
377 return 0;
378 }
379
380
381 VOID
382 CVfrBufferConfig::Close (
383 VOID
384 )
385 {
386 mItemListPos = NULL;
387 }
388
389 #define BYTES_PRE_LINE 0x10
390
391 VOID
392 CVfrBufferConfig::OutputCFile (
393 IN FILE *pFile,
394 IN CHAR8 *BaseName
395 )
396 {
397 CVfrBinaryOutput Output;
398 SConfigItem *Item;
399 SConfigInfo *Info;
400 UINT32 TotalLen;
401
402 if (pFile == NULL) {
403 return;
404 }
405
406 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
407 if (Item->mId != NULL || Item->mInfoStrList == NULL) {
408 continue;
409 }
410 fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
411
412 TotalLen = sizeof (UINT32);
413 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
414 TotalLen += sizeof (UINT16) * 2;
415 }
416 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
417
418 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
419 fprintf (pFile, "\n");
420 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
421 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
422 }
423 fprintf (pFile, "\n};\n");
424 }
425
426 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
427 if (Item->mId != NULL && Item->mInfoStrList != NULL) {
428 fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
429
430 TotalLen = sizeof (UINT32);
431 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
432 TotalLen += Info->mWidth + sizeof (UINT16) * 2;
433 }
434 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
435
436 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
437 fprintf (pFile, "\n");
438 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
439 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
440 if (Info->mNext == NULL) {
441 Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
442 } else {
443 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
444 }
445 }
446 fprintf (pFile, "\n};\n");
447 }
448 }
449 }
450
451 CVfrBufferConfig::CVfrBufferConfig (
452 VOID
453 )
454 {
455 mItemListHead = NULL;
456 mItemListTail = NULL;
457 mItemListPos = NULL;
458 }
459
460 CVfrBufferConfig::~CVfrBufferConfig (
461 VOID
462 )
463 {
464 SConfigItem *p;
465
466 while (mItemListHead != NULL) {
467 p = mItemListHead;
468 mItemListHead = mItemListHead->mNext;
469 delete p;
470 }
471
472 mItemListHead = NULL;
473 mItemListTail = NULL;
474 mItemListPos = NULL;
475 }
476
477 CVfrBufferConfig gCVfrBufferConfig;
478
479 static struct {
480 CONST CHAR8 *mTypeName;
481 UINT8 mType;
482 UINT32 mSize;
483 UINT32 mAlign;
484 } gInternalTypesTable [] = {
485 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},
486 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},
487 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},
488 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},
489 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},
490 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},
491 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
492 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
493 {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},
494 {NULL, EFI_IFR_TYPE_OTHER, 0, 0}
495 };
496
497 STATIC
498 BOOLEAN
499 _IS_INTERNAL_TYPE (
500 IN CHAR8 *TypeName
501 )
502 {
503 UINT32 Index;
504
505 if (TypeName == NULL) {
506 return FALSE;
507 }
508
509 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
510 if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
511 return TRUE;
512 }
513 }
514
515 return FALSE;
516 }
517
518 STATIC
519 CHAR8 *
520 TrimHex (
521 IN CHAR8 *Str,
522 OUT bool *IsHex
523 )
524 {
525 *IsHex = FALSE;
526
527 while (*Str && *Str == ' ') {
528 Str++;
529 }
530 while (*Str && *Str == '0') {
531 Str++;
532 }
533 if (*Str && (*Str == 'x' || *Str == 'X')) {
534 Str++;
535 *IsHex = TRUE;
536 }
537
538 return Str;
539 }
540
541 UINT32
542 _STR2U32 (
543 IN CHAR8 *Str
544 )
545 {
546 bool IsHex;
547 UINT32 Value;
548 CHAR8 c;
549
550 Str = TrimHex (Str, &IsHex);
551 for (Value = 0; (c = *Str) != '\0'; Str++) {
552 //
553 // BUG: does not handle overflow here
554 //
555 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
556
557 if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
558 Value += (c - 'a' + 10);
559 }
560 if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
561 Value += (c - 'A' + 10);
562 }
563 if (c >= '0' && c <= '9') {
564 Value += (c - '0');
565 }
566 }
567
568 return Value;
569 }
570
571 VOID
572 CVfrVarDataTypeDB::RegisterNewType (
573 IN SVfrDataType *New
574 )
575 {
576 New->mNext = mDataTypeList;
577 mDataTypeList = New;
578 }
579
580 EFI_VFR_RETURN_CODE
581 CVfrVarDataTypeDB::ExtractStructTypeName (
582 IN CHAR8 *&VarStr,
583 OUT CHAR8 *TName
584 )
585 {
586 if (TName == NULL) {
587 return VFR_RETURN_FATAL_ERROR;
588 }
589
590 while((*VarStr != '\0') && (*VarStr != '.')) {
591 *TName = *VarStr;
592 VarStr++;
593 TName++;
594 }
595 *TName = '\0';
596 if (*VarStr == '.') {
597 VarStr++;
598 }
599
600 return VFR_RETURN_SUCCESS;
601 }
602
603 EFI_VFR_RETURN_CODE
604 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
605 IN CHAR8 *&VarStr,
606 IN CHAR8 *FName,
607 OUT UINT32 &ArrayIdx
608 )
609 {
610 UINT32 Idx;
611 CHAR8 ArrayStr[MAX_NAME_LEN + 1];
612
613 ArrayIdx = INVALID_ARRAY_INDEX;
614
615 if (FName == NULL) {
616 return VFR_RETURN_FATAL_ERROR;
617 }
618
619 while((*VarStr != '\0') &&
620 (*VarStr != '.') &&
621 (*VarStr != '[') &&
622 (*VarStr != ']')) {
623 *FName = *VarStr;
624 VarStr++;
625 FName++;
626 }
627 *FName = '\0';
628
629 switch (*VarStr) {
630 case '.' :
631 VarStr++;
632 case '\0':
633 return VFR_RETURN_SUCCESS;
634 case '[' :
635 VarStr++;
636 for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
637 ArrayStr[Idx] = *VarStr;
638 }
639 ArrayStr[Idx] = '\0';
640
641 if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
642 return VFR_RETURN_DATA_STRING_ERROR;
643 }
644 ArrayIdx = _STR2U32 (ArrayStr);
645 if (*VarStr == ']') {
646 VarStr++;
647 }
648 if (*VarStr == '.') {
649 VarStr++;
650 }
651 return VFR_RETURN_SUCCESS;
652 case ']':
653 return VFR_RETURN_DATA_STRING_ERROR;
654 }
655
656 return VFR_RETURN_SUCCESS;
657 }
658
659 EFI_VFR_RETURN_CODE
660 CVfrVarDataTypeDB::GetTypeField (
661 IN CONST CHAR8 *FName,
662 IN SVfrDataType *Type,
663 OUT SVfrDataField *&Field
664 )
665 {
666 SVfrDataField *pField = NULL;
667
668 if ((FName == NULL) || (Type == NULL)) {
669 return VFR_RETURN_FATAL_ERROR;
670 }
671
672 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
673 //
674 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
675 // add code to adjust it.
676 //
677 if (Type->mType == EFI_IFR_TYPE_TIME) {
678 if (strcmp (FName, "Hour") == 0) {
679 FName = "Hours";
680 } else if (strcmp (FName, "Minute") == 0) {
681 FName = "Minuts";
682 } else if (strcmp (FName, "Second") == 0) {
683 FName = "Seconds";
684 }
685 }
686
687 if (strcmp (pField->mFieldName, FName) == 0) {
688 Field = pField;
689 return VFR_RETURN_SUCCESS;
690 }
691 }
692
693 return VFR_RETURN_UNDEFINED;
694 }
695
696 EFI_VFR_RETURN_CODE
697 CVfrVarDataTypeDB::GetFieldOffset (
698 IN SVfrDataField *Field,
699 IN UINT32 ArrayIdx,
700 OUT UINT32 &Offset
701 )
702 {
703 if (Field == NULL) {
704 return VFR_RETURN_FATAL_ERROR;
705 }
706
707 //
708 // Framework Vfr file Array Index is from 1.
709 // But Uefi Vfr file Array Index is from 0.
710 //
711 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
712 if (ArrayIdx == 0) {
713 return VFR_RETURN_ERROR_ARRARY_NUM;
714 }
715 ArrayIdx = ArrayIdx - 1;
716 }
717
718 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
719 return VFR_RETURN_ERROR_ARRARY_NUM;
720 }
721
722 //
723 // Be compatible with the current usage
724 // If ArraryIdx is not specified, the first one is used.
725 //
726 // if ArrayNum is larger than zero, ArraryIdx must be specified.
727 //
728 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
729 // return VFR_RETURN_ERROR_ARRARY_NUM;
730 // }
731 //
732
733 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
734 return VFR_RETURN_SUCCESS;
735 }
736
737 UINT8
738 CVfrVarDataTypeDB::GetFieldWidth (
739 IN SVfrDataField *Field
740 )
741 {
742 if (Field == NULL) {
743 return 0;
744 }
745
746 return Field->mFieldType->mType;
747 }
748
749 UINT32
750 CVfrVarDataTypeDB::GetFieldSize (
751 IN SVfrDataField *Field,
752 IN UINT32 ArrayIdx
753 )
754 {
755 if (Field == NULL) {
756 return VFR_RETURN_FATAL_ERROR;
757 }
758
759 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
760 return Field->mFieldType->mTotalSize * Field->mArrayNum;
761 } else {
762 return Field->mFieldType->mTotalSize;
763 }
764 }
765
766 VOID
767 CVfrVarDataTypeDB::InternalTypesListInit (
768 VOID
769 )
770 {
771 SVfrDataType *New = NULL;
772 UINT32 Index;
773
774 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
775 New = new SVfrDataType;
776 if (New != NULL) {
777 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
778 New->mType = gInternalTypesTable[Index].mType;
779 New->mAlign = gInternalTypesTable[Index].mAlign;
780 New->mTotalSize = gInternalTypesTable[Index].mSize;
781 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
782 SVfrDataField *pYearField = new SVfrDataField;
783 SVfrDataField *pMonthField = new SVfrDataField;
784 SVfrDataField *pDayField = new SVfrDataField;
785
786 strcpy (pYearField->mFieldName, "Year");
787 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
788 pYearField->mOffset = 0;
789 pYearField->mNext = pMonthField;
790 pYearField->mArrayNum = 0;
791
792 strcpy (pMonthField->mFieldName, "Month");
793 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
794 pMonthField->mOffset = 2;
795 pMonthField->mNext = pDayField;
796 pMonthField->mArrayNum = 0;
797
798 strcpy (pDayField->mFieldName, "Day");
799 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
800 pDayField->mOffset = 3;
801 pDayField->mNext = NULL;
802 pDayField->mArrayNum = 0;
803
804 New->mMembers = pYearField;
805 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
806 SVfrDataField *pHoursField = new SVfrDataField;
807 SVfrDataField *pMinutesField = new SVfrDataField;
808 SVfrDataField *pSecondsField = new SVfrDataField;
809
810 strcpy (pHoursField->mFieldName, "Hours");
811 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
812 pHoursField->mOffset = 0;
813 pHoursField->mNext = pMinutesField;
814 pHoursField->mArrayNum = 0;
815
816 strcpy (pMinutesField->mFieldName, "Minutes");
817 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
818 pMinutesField->mOffset = 1;
819 pMinutesField->mNext = pSecondsField;
820 pMinutesField->mArrayNum = 0;
821
822 strcpy (pSecondsField->mFieldName, "Seconds");
823 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
824 pSecondsField->mOffset = 2;
825 pSecondsField->mNext = NULL;
826 pSecondsField->mArrayNum = 0;
827
828 New->mMembers = pHoursField;
829 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
830 SVfrDataField *pQuestionIdField = new SVfrDataField;
831 SVfrDataField *pFormIdField = new SVfrDataField;
832 SVfrDataField *pFormSetGuidField = new SVfrDataField;
833 SVfrDataField *pDevicePathField = new SVfrDataField;
834
835 strcpy (pQuestionIdField->mFieldName, "QuestionId");
836 GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
837 pQuestionIdField->mOffset = 0;
838 pQuestionIdField->mNext = pFormIdField;
839 pQuestionIdField->mArrayNum = 0;
840
841 strcpy (pFormIdField->mFieldName, "FormId");
842 GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
843 pFormIdField->mOffset = 2;
844 pFormIdField->mNext = pFormSetGuidField;
845 pFormIdField->mArrayNum = 0;
846
847 strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
848 GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
849 pFormSetGuidField->mOffset = 4;
850 pFormSetGuidField->mNext = pDevicePathField;
851 pFormSetGuidField->mArrayNum = 0;
852
853 strcpy (pDevicePathField->mFieldName, "DevicePath");
854 GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
855 pDevicePathField->mOffset = 20;
856 pDevicePathField->mNext = NULL;
857 pDevicePathField->mArrayNum = 0;
858
859 New->mMembers = pQuestionIdField;
860 } else {
861 New->mMembers = NULL;
862 }
863 New->mNext = NULL;
864 RegisterNewType (New);
865 New = NULL;
866 }
867 }
868 }
869
870 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
871 VOID
872 )
873 {
874 mDataTypeList = NULL;
875 mNewDataType = NULL;
876 mCurrDataField = NULL;
877 mPackAlign = DEFAULT_PACK_ALIGN;
878 mPackStack = NULL;
879 mFirstNewDataTypeName = NULL;
880
881 InternalTypesListInit ();
882 }
883
884 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
885 VOID
886 )
887 {
888 SVfrDataType *pType;
889 SVfrDataField *pField;
890 SVfrPackStackNode *pPack;
891
892 if (mNewDataType != NULL) {
893 delete mNewDataType;
894 }
895
896 while (mDataTypeList != NULL) {
897 pType = mDataTypeList;
898 mDataTypeList = mDataTypeList->mNext;
899 while(pType->mMembers != NULL) {
900 pField = pType->mMembers;
901 pType->mMembers = pType->mMembers->mNext;
902 delete pField;
903 }
904 delete pType;
905 }
906
907 while (mPackStack != NULL) {
908 pPack = mPackStack;
909 mPackStack = mPackStack->mNext;
910 delete pPack;
911 }
912 }
913
914 EFI_VFR_RETURN_CODE
915 CVfrVarDataTypeDB::Pack (
916 IN UINT32 LineNum,
917 IN UINT8 Action,
918 IN CHAR8 *Identifier,
919 IN UINT32 Number
920 )
921 {
922 UINT32 PackAlign;
923 CHAR8 Msg[MAX_STRING_LEN] = {0, };
924
925 if (Action & VFR_PACK_SHOW) {
926 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
927 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
928 }
929
930 if (Action & VFR_PACK_PUSH) {
931 SVfrPackStackNode *pNew = NULL;
932
933 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
934 return VFR_RETURN_FATAL_ERROR;
935 }
936 pNew->mNext = mPackStack;
937 mPackStack = pNew;
938 }
939
940 if (Action & VFR_PACK_POP) {
941 SVfrPackStackNode *pNode = NULL;
942
943 if (mPackStack == NULL) {
944 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
945 }
946
947 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
948 if (pNode->Match (Identifier) == TRUE) {
949 mPackAlign = pNode->mNumber;
950 mPackStack = pNode->mNext;
951 }
952 }
953 }
954
955 if (Action & VFR_PACK_ASSIGN) {
956 PackAlign = (Number > 1) ? Number + Number % 2 : Number;
957 if ((PackAlign == 0) || (PackAlign > 16)) {
958 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
959 } else {
960 mPackAlign = PackAlign;
961 }
962 }
963
964 return VFR_RETURN_SUCCESS;
965 }
966
967 VOID
968 CVfrVarDataTypeDB::DeclareDataTypeBegin (
969 VOID
970 )
971 {
972 SVfrDataType *pNewType = NULL;
973
974 pNewType = new SVfrDataType;
975 pNewType->mTypeName[0] = '\0';
976 pNewType->mType = EFI_IFR_TYPE_OTHER;
977 pNewType->mAlign = DEFAULT_ALIGN;
978 pNewType->mTotalSize = 0;
979 pNewType->mMembers = NULL;
980 pNewType->mNext = NULL;
981
982 mNewDataType = pNewType;
983 }
984
985 EFI_VFR_RETURN_CODE
986 CVfrVarDataTypeDB::SetNewTypeName (
987 IN CHAR8 *TypeName
988 )
989 {
990 SVfrDataType *pType;
991
992 if (mNewDataType == NULL) {
993 return VFR_RETURN_ERROR_SKIPED;
994 }
995 if (TypeName == NULL) {
996 return VFR_RETURN_FATAL_ERROR;
997 }
998 if (strlen(TypeName) >= MAX_NAME_LEN) {
999 return VFR_RETURN_INVALID_PARAMETER;
1000 }
1001
1002 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1003 if (strcmp(pType->mTypeName, TypeName) == 0) {
1004 return VFR_RETURN_REDEFINED;
1005 }
1006 }
1007
1008 strcpy(mNewDataType->mTypeName, TypeName);
1009 return VFR_RETURN_SUCCESS;
1010 }
1011
1012 EFI_VFR_RETURN_CODE
1013 CVfrVarDataTypeDB::DataTypeAddField (
1014 IN CHAR8 *FieldName,
1015 IN CHAR8 *TypeName,
1016 IN UINT32 ArrayNum
1017 )
1018 {
1019 SVfrDataField *pNewField = NULL;
1020 SVfrDataType *pFieldType = NULL;
1021 SVfrDataField *pTmp;
1022 UINT32 Align;
1023
1024 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
1025
1026 if (strlen (FieldName) >= MAX_NAME_LEN) {
1027 return VFR_RETURN_INVALID_PARAMETER;
1028 }
1029
1030 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
1031 if (strcmp (pTmp->mFieldName, FieldName) == 0) {
1032 return VFR_RETURN_REDEFINED;
1033 }
1034 }
1035
1036 Align = MIN (mPackAlign, pFieldType->mAlign);
1037
1038 if ((pNewField = new SVfrDataField) == NULL) {
1039 return VFR_RETURN_OUT_FOR_RESOURCES;
1040 }
1041 strcpy (pNewField->mFieldName, FieldName);
1042 pNewField->mFieldType = pFieldType;
1043 pNewField->mArrayNum = ArrayNum;
1044 if ((mNewDataType->mTotalSize % Align) == 0) {
1045 pNewField->mOffset = mNewDataType->mTotalSize;
1046 } else {
1047 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
1048 }
1049 if (mNewDataType->mMembers == NULL) {
1050 mNewDataType->mMembers = pNewField;
1051 pNewField->mNext = NULL;
1052 } else {
1053 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
1054 ;
1055 pTmp->mNext = pNewField;
1056 pNewField->mNext = NULL;
1057 }
1058
1059 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
1060 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
1061
1062 return VFR_RETURN_SUCCESS;
1063 }
1064
1065 VOID
1066 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1067 VOID
1068 )
1069 {
1070 if (mNewDataType->mTypeName[0] == '\0') {
1071 return;
1072 }
1073
1074 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
1075 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
1076 }
1077
1078 RegisterNewType (mNewDataType);
1079 if (mFirstNewDataTypeName == NULL) {
1080 mFirstNewDataTypeName = mNewDataType->mTypeName;
1081 }
1082
1083 mNewDataType = NULL;
1084 }
1085
1086 EFI_VFR_RETURN_CODE
1087 CVfrVarDataTypeDB::GetDataType (
1088 IN CHAR8 *TypeName,
1089 OUT SVfrDataType **DataType
1090 )
1091 {
1092 SVfrDataType *pDataType = NULL;
1093
1094 if (TypeName == NULL) {
1095 return VFR_RETURN_ERROR_SKIPED;
1096 }
1097
1098 if (DataType == NULL) {
1099 return VFR_RETURN_FATAL_ERROR;
1100 }
1101
1102 *DataType = NULL;
1103
1104 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1105 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1106 *DataType = pDataType;
1107 return VFR_RETURN_SUCCESS;
1108 }
1109 }
1110
1111 return VFR_RETURN_UNDEFINED;
1112 }
1113
1114 EFI_VFR_RETURN_CODE
1115 CVfrVarDataTypeDB::GetDataTypeSize (
1116 IN UINT8 DataType,
1117 OUT UINT32 *Size
1118 )
1119 {
1120 SVfrDataType *pDataType = NULL;
1121
1122 if (Size == NULL) {
1123 return VFR_RETURN_FATAL_ERROR;
1124 }
1125
1126 *Size = 0;
1127 DataType = DataType & 0x0F;
1128
1129 //
1130 // For user defined data type, the size can't be got by this function.
1131 //
1132 if (DataType == EFI_IFR_TYPE_OTHER) {
1133 return VFR_RETURN_SUCCESS;
1134 }
1135
1136 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1137 if (DataType == pDataType->mType) {
1138 *Size = pDataType->mTotalSize;
1139 return VFR_RETURN_SUCCESS;
1140 }
1141 }
1142
1143 return VFR_RETURN_UNDEFINED;
1144 }
1145
1146 EFI_VFR_RETURN_CODE
1147 CVfrVarDataTypeDB::GetDataTypeSize (
1148 IN CHAR8 *TypeName,
1149 OUT UINT32 *Size
1150 )
1151 {
1152 SVfrDataType *pDataType = NULL;
1153
1154 if (Size == NULL) {
1155 return VFR_RETURN_FATAL_ERROR;
1156 }
1157
1158 *Size = 0;
1159
1160 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1161 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1162 *Size = pDataType->mTotalSize;
1163 return VFR_RETURN_SUCCESS;
1164 }
1165 }
1166
1167 return VFR_RETURN_UNDEFINED;
1168 }
1169
1170 EFI_VFR_RETURN_CODE
1171 CVfrVarDataTypeDB::GetDataFieldInfo (
1172 IN CHAR8 *VarStr,
1173 OUT UINT16 &Offset,
1174 OUT UINT8 &Type,
1175 OUT UINT32 &Size
1176 )
1177 {
1178 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
1179 UINT32 ArrayIdx, Tmp;
1180 SVfrDataType *pType = NULL;
1181 SVfrDataField *pField = NULL;
1182
1183 Offset = 0;
1184 Type = EFI_IFR_TYPE_OTHER;
1185 Size = 0;
1186
1187 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
1188 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
1189
1190 //
1191 // if it is not struct data type
1192 //
1193 Type = pType->mType;
1194 Size = pType->mTotalSize;
1195
1196 while (*VarStr != '\0') {
1197 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
1198 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
1199 pType = pField->mFieldType;
1200 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
1201 Offset = (UINT16) (Offset + Tmp);
1202 Type = GetFieldWidth (pField);
1203 Size = GetFieldSize (pField, ArrayIdx);
1204 }
1205 return VFR_RETURN_SUCCESS;
1206 }
1207
1208 EFI_VFR_RETURN_CODE
1209 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1210 OUT CHAR8 ***NameList,
1211 OUT UINT32 *ListSize
1212 )
1213 {
1214 UINT32 Index;
1215 SVfrDataType *pType;
1216
1217 if ((NameList == NULL) || (ListSize == NULL)) {
1218 return VFR_RETURN_FATAL_ERROR;
1219 }
1220
1221 *NameList = NULL;
1222 *ListSize = 0;
1223
1224 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1225 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1226 (*ListSize)++;
1227 }
1228 }
1229
1230 if (*ListSize == 0) {
1231 return VFR_RETURN_SUCCESS;
1232 }
1233
1234 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
1235 *ListSize = 0;
1236 return VFR_RETURN_OUT_FOR_RESOURCES;
1237 }
1238
1239 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
1240 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1241 (*NameList)[Index] = pType->mTypeName;
1242 }
1243 }
1244 return VFR_RETURN_SUCCESS;
1245 }
1246
1247 BOOLEAN
1248 CVfrVarDataTypeDB::IsTypeNameDefined (
1249 IN CHAR8 *TypeName
1250 )
1251 {
1252 SVfrDataType *pType;
1253
1254 if (TypeName == NULL) {
1255 return FALSE;
1256 }
1257
1258 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1259 if (strcmp (pType->mTypeName, TypeName) == 0) {
1260 return TRUE;
1261 }
1262 }
1263
1264 return FALSE;
1265 }
1266
1267 VOID
1268 CVfrVarDataTypeDB::Dump (
1269 IN FILE *File
1270 )
1271 {
1272 SVfrDataType *pTNode;
1273 SVfrDataField *pFNode;
1274
1275 fprintf (File, "\n\n***************************************************************\n");
1276 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
1277 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1278 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1279 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
1280 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1281 if (pFNode->mArrayNum > 0) {
1282 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
1283 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
1284 } else {
1285 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
1286 pFNode->mFieldName, pFNode->mFieldType->mTypeName);
1287 }
1288 }
1289 fprintf (File, "\t\t};\n");
1290 fprintf (File, "---------------------------------------------------------------\n");
1291 }
1292 fprintf (File, "***************************************************************\n");
1293 }
1294
1295 #ifdef CVFR_VARDATATYPEDB_DEBUG
1296 VOID
1297 CVfrVarDataTypeDB::ParserDB (
1298 VOID
1299 )
1300 {
1301 SVfrDataType *pTNode;
1302 SVfrDataField *pFNode;
1303
1304 printf ("***************************************************************\n");
1305 printf ("\t\tmPackAlign = %x\n", mPackAlign);
1306 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1307 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1308 printf ("\t\tstruct %s {\n", pTNode->mTypeName);
1309 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1310 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
1311 }
1312 printf ("\t\t};\n");
1313 printf ("---------------------------------------------------------------\n");
1314 }
1315 printf ("***************************************************************\n");
1316 }
1317 #endif
1318
1319 SVfrVarStorageNode::SVfrVarStorageNode (
1320 IN EFI_GUID *Guid,
1321 IN CHAR8 *StoreName,
1322 IN EFI_VARSTORE_ID VarStoreId,
1323 IN EFI_STRING_ID VarName,
1324 IN UINT32 VarSize,
1325 IN BOOLEAN Flag
1326 )
1327 {
1328 if (Guid != NULL) {
1329 mGuid = *Guid;
1330 } else {
1331 memset (&mGuid, 0, sizeof (EFI_GUID));
1332 }
1333 if (StoreName != NULL) {
1334 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1335 strcpy (mVarStoreName, StoreName);
1336 } else {
1337 mVarStoreName = NULL;
1338 }
1339 mNext = NULL;
1340 mVarStoreId = VarStoreId;
1341 mVarStoreType = EFI_VFR_VARSTORE_EFI;
1342 mStorageInfo.mEfiVar.mEfiVarName = VarName;
1343 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
1344 mAssignedFlag = Flag;
1345 }
1346
1347 SVfrVarStorageNode::SVfrVarStorageNode (
1348 IN EFI_GUID *Guid,
1349 IN CHAR8 *StoreName,
1350 IN EFI_VARSTORE_ID VarStoreId,
1351 IN SVfrDataType *DataType,
1352 IN BOOLEAN Flag
1353 )
1354 {
1355 if (Guid != NULL) {
1356 mGuid = *Guid;
1357 } else {
1358 memset (&mGuid, 0, sizeof (EFI_GUID));
1359 }
1360 if (StoreName != NULL) {
1361 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1362 strcpy (mVarStoreName, StoreName);
1363 } else {
1364 mVarStoreName = NULL;
1365 }
1366 mNext = NULL;
1367 mVarStoreId = VarStoreId;
1368 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
1369 mStorageInfo.mDataType = DataType;
1370 mAssignedFlag = Flag;
1371 }
1372
1373 SVfrVarStorageNode::SVfrVarStorageNode (
1374 IN CHAR8 *StoreName,
1375 IN EFI_VARSTORE_ID VarStoreId
1376 )
1377 {
1378 if (StoreName != NULL) {
1379 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1380 strcpy (mVarStoreName, StoreName);
1381 } else {
1382 mVarStoreName = NULL;
1383 }
1384 mNext = NULL;
1385 mVarStoreId = VarStoreId;
1386 mVarStoreType = EFI_VFR_VARSTORE_NAME;
1387 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
1388 mStorageInfo.mNameSpace.mTableSize = 0;
1389 }
1390
1391 SVfrVarStorageNode::~SVfrVarStorageNode (
1392 VOID
1393 )
1394 {
1395 if (mVarStoreName != NULL) {
1396 delete mVarStoreName;
1397 }
1398
1399 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
1400 delete mStorageInfo.mNameSpace.mNameTable;
1401 }
1402 }
1403
1404 CVfrDataStorage::CVfrDataStorage (
1405 VOID
1406 )
1407 {
1408 UINT32 Index;
1409
1410 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1411 mFreeVarStoreIdBitMap[Index] = 0;
1412 }
1413
1414 // Question ID 0 is reserved.
1415 mFreeVarStoreIdBitMap[0] = 0x80000000;
1416
1417 mBufferVarStoreList = NULL;
1418 mEfiVarStoreList = NULL;
1419 mNameVarStoreList = NULL;
1420 mCurrVarStorageNode = NULL;
1421 mNewVarStorageNode = NULL;
1422 mBufferFieldInfoListHead = NULL;
1423 mBufferFieldInfoListTail = NULL;
1424 }
1425
1426 CVfrDataStorage::~CVfrDataStorage (
1427 VOID
1428 )
1429 {
1430 SVfrVarStorageNode *pNode;
1431
1432 while (mBufferVarStoreList != NULL) {
1433 pNode = mBufferVarStoreList;
1434 mBufferVarStoreList = mBufferVarStoreList->mNext;
1435 delete pNode;
1436 }
1437 while (mEfiVarStoreList != NULL) {
1438 pNode = mEfiVarStoreList;
1439 mEfiVarStoreList = mEfiVarStoreList->mNext;
1440 delete pNode;
1441 }
1442 while (mNameVarStoreList != NULL) {
1443 pNode = mNameVarStoreList;
1444 mNameVarStoreList = mNameVarStoreList->mNext;
1445 delete pNode;
1446 }
1447 if (mNewVarStorageNode != NULL) {
1448 delete mNewVarStorageNode;
1449 }
1450 }
1451
1452 EFI_VARSTORE_ID
1453 CVfrDataStorage::GetFreeVarStoreId (
1454 EFI_VFR_VARSTORE_TYPE VarType
1455 )
1456 {
1457 UINT32 Index, Mask, Offset;
1458
1459 //
1460 // Assign the different ID range for the different type VarStore to support Framework Vfr
1461 //
1462 Index = 0;
1463 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
1464 Index = 0;
1465 } else if (VarType == EFI_VFR_VARSTORE_EFI) {
1466 Index = 1;
1467 } else if (VarType == EFI_VFR_VARSTORE_NAME) {
1468 Index = 2;
1469 }
1470
1471 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1472 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1473 break;
1474 }
1475 }
1476
1477 if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
1478 return EFI_VARSTORE_ID_INVALID;
1479 }
1480
1481 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1482 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1483 mFreeVarStoreIdBitMap[Index] |= Mask;
1484 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1485 }
1486 }
1487
1488 return EFI_VARSTORE_ID_INVALID;
1489 }
1490
1491 BOOLEAN
1492 CVfrDataStorage::ChekVarStoreIdFree (
1493 IN EFI_VARSTORE_ID VarStoreId
1494 )
1495 {
1496 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1497 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1498
1499 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1500 }
1501
1502 VOID
1503 CVfrDataStorage::MarkVarStoreIdUsed (
1504 IN EFI_VARSTORE_ID VarStoreId
1505 )
1506 {
1507 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1508 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1509
1510 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1511 }
1512
1513 VOID
1514 CVfrDataStorage::MarkVarStoreIdUnused (
1515 IN EFI_VARSTORE_ID VarStoreId
1516 )
1517 {
1518 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1519 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1520
1521 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1522 }
1523
1524 EFI_VFR_RETURN_CODE
1525 CVfrDataStorage::DeclareNameVarStoreBegin (
1526 IN CHAR8 *StoreName,
1527 IN EFI_VARSTORE_ID VarStoreId
1528 )
1529 {
1530 SVfrVarStorageNode *pNode = NULL;
1531 EFI_VARSTORE_ID TmpVarStoreId;
1532
1533 if (StoreName == NULL) {
1534 return VFR_RETURN_FATAL_ERROR;
1535 }
1536
1537 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
1538 return VFR_RETURN_REDEFINED;
1539 }
1540
1541 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1542 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1543 } else {
1544 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1545 return VFR_RETURN_VARSTOREID_REDEFINED;
1546 }
1547 MarkVarStoreIdUsed (VarStoreId);
1548 }
1549
1550 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1551 return VFR_RETURN_UNDEFINED;
1552 }
1553
1554 mNewVarStorageNode = pNode;
1555
1556 return VFR_RETURN_SUCCESS;
1557 }
1558
1559 EFI_VFR_RETURN_CODE
1560 CVfrDataStorage::NameTableAddItem (
1561 IN EFI_STRING_ID Item
1562 )
1563 {
1564 EFI_VARSTORE_ID *NewTable, *OldTable;
1565 UINT32 TableSize;
1566
1567 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1568 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1569
1570 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1571 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1572 return VFR_RETURN_OUT_FOR_RESOURCES;
1573 }
1574 memcpy (NewTable, OldTable, TableSize);
1575 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1576 }
1577
1578 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1579 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1580
1581 return VFR_RETURN_SUCCESS;
1582 }
1583
1584 EFI_VFR_RETURN_CODE
1585 CVfrDataStorage::DeclareNameVarStoreEnd (
1586 IN EFI_GUID *Guid
1587 )
1588 {
1589 mNewVarStorageNode->mGuid = *Guid;
1590 mNewVarStorageNode->mNext = mNameVarStoreList;
1591 mNameVarStoreList = mNewVarStorageNode;
1592
1593 mNewVarStorageNode = NULL;
1594
1595 return VFR_RETURN_SUCCESS;
1596 }
1597
1598 EFI_VFR_RETURN_CODE
1599 CVfrDataStorage::DeclareEfiVarStore (
1600 IN CHAR8 *StoreName,
1601 IN EFI_GUID *Guid,
1602 IN EFI_STRING_ID NameStrId,
1603 IN UINT32 VarSize,
1604 IN BOOLEAN Flag
1605 )
1606 {
1607 SVfrVarStorageNode *pNode;
1608 EFI_VARSTORE_ID VarStoreId;
1609
1610 if ((StoreName == NULL) || (Guid == NULL)) {
1611 return VFR_RETURN_FATAL_ERROR;
1612 }
1613
1614 if (VarSize > sizeof (UINT64)) {
1615 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1616 }
1617
1618 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1619 return VFR_RETURN_REDEFINED;
1620 }
1621
1622 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
1623 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
1624 return VFR_RETURN_OUT_FOR_RESOURCES;
1625 }
1626
1627 pNode->mNext = mEfiVarStoreList;
1628 mEfiVarStoreList = pNode;
1629
1630 return VFR_RETURN_SUCCESS;
1631 }
1632
1633 EFI_VFR_RETURN_CODE
1634 CVfrDataStorage::DeclareBufferVarStore (
1635 IN CHAR8 *StoreName,
1636 IN EFI_GUID *Guid,
1637 IN CVfrVarDataTypeDB *DataTypeDB,
1638 IN CHAR8 *TypeName,
1639 IN EFI_VARSTORE_ID VarStoreId,
1640 IN BOOLEAN Flag
1641 )
1642 {
1643 SVfrVarStorageNode *pNew = NULL;
1644 SVfrDataType *pDataType = NULL;
1645 EFI_VARSTORE_ID TempVarStoreId;
1646
1647 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1648 return VFR_RETURN_FATAL_ERROR;
1649 }
1650
1651 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1652 return VFR_RETURN_REDEFINED;
1653 }
1654
1655 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1656
1657 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1658 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1659 } else {
1660 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1661 return VFR_RETURN_VARSTOREID_REDEFINED;
1662 }
1663 MarkVarStoreIdUsed (VarStoreId);
1664 }
1665
1666 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
1667 return VFR_RETURN_OUT_FOR_RESOURCES;
1668 }
1669
1670 pNew->mNext = mBufferVarStoreList;
1671 mBufferVarStoreList = pNew;
1672
1673 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
1674 return VFR_RETURN_FATAL_ERROR;
1675 }
1676
1677 return VFR_RETURN_SUCCESS;
1678 }
1679
1680 EFI_VFR_RETURN_CODE
1681 CVfrDataStorage::GetVarStoreByDataType (
1682 IN CHAR8 *DataTypeName,
1683 OUT SVfrVarStorageNode **VarNode,
1684 IN EFI_GUID *VarGuid
1685 )
1686 {
1687 SVfrVarStorageNode *pNode;
1688 SVfrVarStorageNode *MatchNode;
1689
1690 //
1691 // Framework VFR uses Data type name as varstore name, so don't need check again.
1692 //
1693 if (VfrCompatibleMode) {
1694 return VFR_RETURN_UNDEFINED;
1695 }
1696
1697 MatchNode = NULL;
1698 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1699 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
1700 continue;
1701 }
1702
1703 if ((VarGuid != NULL)) {
1704 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1705 *VarNode = pNode;
1706 return VFR_RETURN_SUCCESS;
1707 }
1708 } else {
1709 if (MatchNode == NULL) {
1710 MatchNode = pNode;
1711 } else {
1712 //
1713 // More than one varstores referred the same data structures.
1714 //
1715 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
1716 }
1717 }
1718 }
1719
1720 if (MatchNode == NULL) {
1721 return VFR_RETURN_UNDEFINED;
1722 }
1723
1724 *VarNode = MatchNode;
1725 return VFR_RETURN_SUCCESS;
1726 }
1727
1728 EFI_VARSTORE_ID
1729 CVfrDataStorage::CheckGuidField (
1730 IN SVfrVarStorageNode *pNode,
1731 IN EFI_GUID *StoreGuid,
1732 IN BOOLEAN *HasFoundOne,
1733 OUT EFI_VFR_RETURN_CODE *ReturnCode
1734 )
1735 {
1736 if (StoreGuid != NULL) {
1737 //
1738 // If has guid info, compare the guid filed.
1739 //
1740 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1741 //
1742 // Both name and guid are same, this this varstore.
1743 //
1744 mCurrVarStorageNode = pNode;
1745 *ReturnCode = VFR_RETURN_SUCCESS;
1746 return TRUE;
1747 }
1748 } else {
1749 //
1750 // Not has Guid field, check whether this name is the only one.
1751 //
1752 if (*HasFoundOne) {
1753 //
1754 // The name has conflict, return name redefined.
1755 //
1756 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
1757 return TRUE;
1758 }
1759
1760 *HasFoundOne = TRUE;
1761 mCurrVarStorageNode = pNode;
1762 }
1763
1764 return FALSE;
1765 }
1766
1767 /**
1768 Base on the input store name and guid to find the varstore id.
1769
1770 If both name and guid are inputed, base on the name and guid to
1771 found the varstore. If only name inputed, base on the name to
1772 found the varstore and go on to check whether more than one varstore
1773 has the same name. If only has found one varstore, return this
1774 varstore; if more than one varstore has same name, return varstore
1775 name redefined error. If no varstore found by varstore name, call
1776 function GetVarStoreByDataType and use inputed varstore name as
1777 data type name to search.
1778 **/
1779 EFI_VFR_RETURN_CODE
1780 CVfrDataStorage::GetVarStoreId (
1781 IN CHAR8 *StoreName,
1782 OUT EFI_VARSTORE_ID *VarStoreId,
1783 IN EFI_GUID *StoreGuid
1784 )
1785 {
1786 EFI_VFR_RETURN_CODE ReturnCode;
1787 SVfrVarStorageNode *pNode;
1788 BOOLEAN HasFoundOne = FALSE;
1789
1790 mCurrVarStorageNode = NULL;
1791
1792 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1793 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1794 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1795 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1796 return ReturnCode;
1797 }
1798 }
1799 }
1800
1801 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1802 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1803 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1804 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1805 return ReturnCode;
1806 }
1807 }
1808 }
1809
1810 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1811 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1812 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1813 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1814 return ReturnCode;
1815 }
1816 }
1817 }
1818
1819 if (HasFoundOne) {
1820 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1821 return VFR_RETURN_SUCCESS;
1822 }
1823
1824 *VarStoreId = EFI_VARSTORE_ID_INVALID;
1825
1826 //
1827 // Assume that Data strucutre name is used as StoreName, and check again.
1828 //
1829 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
1830 if (pNode != NULL) {
1831 mCurrVarStorageNode = pNode;
1832 *VarStoreId = pNode->mVarStoreId;
1833 }
1834
1835 return ReturnCode;
1836 }
1837
1838 EFI_VFR_RETURN_CODE
1839 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1840 IN EFI_VARSTORE_ID VarStoreId,
1841 OUT CHAR8 **DataTypeName
1842 )
1843 {
1844 SVfrVarStorageNode *pNode;
1845
1846 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1847 return VFR_RETURN_FATAL_ERROR;
1848 }
1849
1850 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1851 if (pNode->mVarStoreId == VarStoreId) {
1852 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
1853 return VFR_RETURN_SUCCESS;
1854 }
1855 }
1856
1857 return VFR_RETURN_UNDEFINED;
1858 }
1859
1860 EFI_VFR_VARSTORE_TYPE
1861 CVfrDataStorage::GetVarStoreType (
1862 IN EFI_VARSTORE_ID VarStoreId
1863 )
1864 {
1865 SVfrVarStorageNode *pNode;
1866 EFI_VFR_VARSTORE_TYPE VarStoreType;
1867
1868 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1869
1870 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1871 return VarStoreType;
1872 }
1873
1874 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1875 if (pNode->mVarStoreId == VarStoreId) {
1876 VarStoreType = pNode->mVarStoreType;
1877 return VarStoreType;
1878 }
1879 }
1880
1881 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1882 if (pNode->mVarStoreId == VarStoreId) {
1883 VarStoreType = pNode->mVarStoreType;
1884 return VarStoreType;
1885 }
1886 }
1887
1888 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1889 if (pNode->mVarStoreId == VarStoreId) {
1890 VarStoreType = pNode->mVarStoreType;
1891 return VarStoreType;
1892 }
1893 }
1894
1895 return VarStoreType;
1896 }
1897
1898 EFI_GUID *
1899 CVfrDataStorage::GetVarStoreGuid (
1900 IN EFI_VARSTORE_ID VarStoreId
1901 )
1902 {
1903 SVfrVarStorageNode *pNode;
1904 EFI_GUID *VarGuid;
1905
1906 VarGuid = NULL;
1907
1908 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1909 return VarGuid;
1910 }
1911
1912 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1913 if (pNode->mVarStoreId == VarStoreId) {
1914 VarGuid = &pNode->mGuid;
1915 return VarGuid;
1916 }
1917 }
1918
1919 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1920 if (pNode->mVarStoreId == VarStoreId) {
1921 VarGuid = &pNode->mGuid;
1922 return VarGuid;
1923 }
1924 }
1925
1926 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1927 if (pNode->mVarStoreId == VarStoreId) {
1928 VarGuid = &pNode->mGuid;
1929 return VarGuid;
1930 }
1931 }
1932
1933 return VarGuid;
1934 }
1935
1936 EFI_VFR_RETURN_CODE
1937 CVfrDataStorage::GetVarStoreName (
1938 IN EFI_VARSTORE_ID VarStoreId,
1939 OUT CHAR8 **VarStoreName
1940 )
1941 {
1942 SVfrVarStorageNode *pNode;
1943
1944 if (VarStoreName == NULL) {
1945 return VFR_RETURN_FATAL_ERROR;
1946 }
1947
1948 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1949 if (pNode->mVarStoreId == VarStoreId) {
1950 *VarStoreName = pNode->mVarStoreName;
1951 return VFR_RETURN_SUCCESS;
1952 }
1953 }
1954
1955 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1956 if (pNode->mVarStoreId == VarStoreId) {
1957 *VarStoreName = pNode->mVarStoreName;
1958 return VFR_RETURN_SUCCESS;
1959 }
1960 }
1961
1962 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1963 if (pNode->mVarStoreId == VarStoreId) {
1964 *VarStoreName = pNode->mVarStoreName;
1965 return VFR_RETURN_SUCCESS;
1966 }
1967 }
1968
1969 *VarStoreName = NULL;
1970 return VFR_RETURN_UNDEFINED;
1971 }
1972
1973 EFI_VFR_RETURN_CODE
1974 CVfrDataStorage::GetEfiVarStoreInfo (
1975 IN OUT EFI_VARSTORE_INFO *Info
1976 )
1977 {
1978 if (Info == NULL) {
1979 return VFR_RETURN_FATAL_ERROR;
1980 }
1981
1982 if (mCurrVarStorageNode == NULL) {
1983 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
1984 }
1985
1986 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
1987 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
1988 switch (Info->mVarTotalSize) {
1989 case 1:
1990 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
1991 break;
1992 case 2:
1993 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
1994 break;
1995 case 4:
1996 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
1997 break;
1998 case 8:
1999 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
2000 break;
2001 default :
2002 return VFR_RETURN_FATAL_ERROR;
2003 }
2004
2005 return VFR_RETURN_SUCCESS;
2006 }
2007
2008 EFI_VFR_RETURN_CODE
2009 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2010 IN EFI_VARSTORE_INFO *Info
2011 )
2012 {
2013 BufferVarStoreFieldInfoNode *pNew;
2014
2015 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
2016 return VFR_RETURN_FATAL_ERROR;
2017 }
2018
2019 if (mBufferFieldInfoListHead == NULL) {
2020 mBufferFieldInfoListHead = pNew;
2021 mBufferFieldInfoListTail= pNew;
2022 } else {
2023 mBufferFieldInfoListTail->mNext = pNew;
2024 mBufferFieldInfoListTail = pNew;
2025 }
2026
2027 return VFR_RETURN_SUCCESS;
2028 }
2029
2030 EFI_VFR_RETURN_CODE
2031 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2032 IN OUT EFI_VARSTORE_INFO *Info
2033 )
2034 {
2035 BufferVarStoreFieldInfoNode *pNode;
2036
2037 pNode = mBufferFieldInfoListHead;
2038 while (pNode != NULL) {
2039 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
2040 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
2041 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
2042 Info->mVarType = pNode->mVarStoreInfo.mVarType;
2043 return VFR_RETURN_SUCCESS;
2044 }
2045 pNode = pNode->mNext;
2046 }
2047 return VFR_RETURN_FATAL_ERROR;
2048 }
2049
2050 EFI_VFR_RETURN_CODE
2051 CVfrDataStorage::GetNameVarStoreInfo (
2052 OUT EFI_VARSTORE_INFO *Info,
2053 IN UINT32 Index
2054 )
2055 {
2056 if (Info == NULL) {
2057 return VFR_RETURN_FATAL_ERROR;
2058 }
2059
2060 if (mCurrVarStorageNode == NULL) {
2061 return VFR_RETURN_GET_NVVARSTORE_ERROR;
2062 }
2063
2064 //
2065 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2066 //
2067 if (VfrCompatibleMode) {
2068 if (Index == 0) {
2069 return VFR_RETURN_ERROR_ARRARY_NUM;
2070 }
2071 Index --;
2072 }
2073
2074 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
2075
2076 return VFR_RETURN_SUCCESS;
2077 }
2078
2079 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2080 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
2081 IN CHAR8 *RefName,
2082 IN EFI_STRING_ID DefaultStoreNameId,
2083 IN UINT16 DefaultId
2084 )
2085 {
2086 mObjBinAddr = ObjBinAddr;
2087
2088 if (RefName != NULL) {
2089 mRefName = new CHAR8[strlen (RefName) + 1];
2090 strcpy (mRefName, RefName);
2091 } else {
2092 mRefName = NULL;
2093 }
2094
2095 mNext = NULL;
2096 mDefaultId = DefaultId;
2097 mDefaultStoreNameId = DefaultStoreNameId;
2098 }
2099
2100 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2101 VOID
2102 )
2103 {
2104 if (mRefName != NULL) {
2105 delete mRefName;
2106 }
2107 }
2108
2109 CVfrDefaultStore::CVfrDefaultStore (
2110 VOID
2111 )
2112 {
2113 mDefaultStoreList = NULL;
2114 }
2115
2116 CVfrDefaultStore::~CVfrDefaultStore (
2117 VOID
2118 )
2119 {
2120 SVfrDefaultStoreNode *pTmp = NULL;
2121
2122 while (mDefaultStoreList != NULL) {
2123 pTmp = mDefaultStoreList;
2124 mDefaultStoreList = mDefaultStoreList->mNext;
2125 delete pTmp;
2126 }
2127 }
2128
2129 EFI_VFR_RETURN_CODE
2130 CVfrDefaultStore::RegisterDefaultStore (
2131 IN CHAR8 *ObjBinAddr,
2132 IN CHAR8 *RefName,
2133 IN EFI_STRING_ID DefaultStoreNameId,
2134 IN UINT16 DefaultId
2135 )
2136 {
2137 SVfrDefaultStoreNode *pNode = NULL;
2138
2139 if (RefName == NULL) {
2140 return VFR_RETURN_FATAL_ERROR;
2141 }
2142
2143 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2144 if (strcmp (pNode->mRefName, RefName) == 0) {
2145 return VFR_RETURN_REDEFINED;
2146 }
2147 }
2148
2149 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
2150 return VFR_RETURN_OUT_FOR_RESOURCES;
2151 }
2152
2153 pNode->mNext = mDefaultStoreList;
2154 mDefaultStoreList = pNode;
2155
2156 return VFR_RETURN_SUCCESS;
2157 }
2158
2159 /*
2160 * assign new reference name or new default store name id only if
2161 * the original is invalid
2162 */
2163 EFI_VFR_RETURN_CODE
2164 CVfrDefaultStore::ReRegisterDefaultStoreById (
2165 IN UINT16 DefaultId,
2166 IN CHAR8 *RefName,
2167 IN EFI_STRING_ID DefaultStoreNameId
2168 )
2169 {
2170 SVfrDefaultStoreNode *pNode = NULL;
2171
2172 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2173 if (pNode->mDefaultId == DefaultId) {
2174 break;
2175 }
2176 }
2177
2178 if (pNode == NULL) {
2179 return VFR_RETURN_UNDEFINED;
2180 } else {
2181 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
2182 pNode->mDefaultStoreNameId = DefaultStoreNameId;
2183 if (pNode->mObjBinAddr != NULL) {
2184 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
2185 }
2186 } else {
2187 return VFR_RETURN_REDEFINED;
2188 }
2189
2190 if (RefName != NULL) {
2191 delete pNode->mRefName;
2192 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
2193 if (pNode->mRefName != NULL) {
2194 strcpy (pNode->mRefName, RefName);
2195 }
2196 }
2197 }
2198
2199 return VFR_RETURN_SUCCESS;
2200 }
2201
2202 BOOLEAN
2203 CVfrDefaultStore::DefaultIdRegistered (
2204 IN UINT16 DefaultId
2205 )
2206 {
2207 SVfrDefaultStoreNode *pNode = NULL;
2208
2209 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2210 if (pNode->mDefaultId == DefaultId) {
2211 return TRUE;
2212 }
2213 }
2214
2215 return FALSE;
2216 }
2217
2218 EFI_VFR_RETURN_CODE
2219 CVfrDefaultStore::GetDefaultId (
2220 IN CHAR8 *RefName,
2221 OUT UINT16 *DefaultId
2222 )
2223 {
2224 SVfrDefaultStoreNode *pTmp = NULL;
2225
2226 if (DefaultId == NULL) {
2227 return VFR_RETURN_FATAL_ERROR;
2228 }
2229
2230 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2231 if (strcmp (pTmp->mRefName, RefName) == 0) {
2232 *DefaultId = pTmp->mDefaultId;
2233 return VFR_RETURN_SUCCESS;
2234 }
2235 }
2236
2237 return VFR_RETURN_UNDEFINED;
2238 }
2239
2240 EFI_VFR_RETURN_CODE
2241 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2242 IN EFI_VARSTORE_ID DefaultId,
2243 IN EFI_VARSTORE_INFO &Info,
2244 IN CHAR8 *VarStoreName,
2245 IN EFI_GUID *VarStoreGuid,
2246 IN UINT8 Type,
2247 IN EFI_IFR_TYPE_VALUE Value
2248 )
2249 {
2250 SVfrDefaultStoreNode *pNode = NULL;
2251 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2252 INTN Returnvalue = 0;
2253
2254 if (VarStoreName == NULL) {
2255 return VFR_RETURN_FATAL_ERROR;
2256 }
2257
2258 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2259 if (pNode->mDefaultId == DefaultId) {
2260 break;
2261 }
2262 }
2263
2264 if (pNode == NULL) {
2265 return VFR_RETURN_UNDEFINED;
2266 }
2267
2268 gCVfrBufferConfig.Open ();
2269
2270 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2271 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
2272 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2273 goto WriteError;
2274 }
2275 }
2276
2277 gCVfrBufferConfig.Close ();
2278
2279 return VFR_RETURN_SUCCESS;
2280
2281 WriteError:
2282 gCVfrBufferConfig.Close ();
2283 return (EFI_VFR_RETURN_CODE)Returnvalue;
2284 }
2285
2286 SVfrRuleNode::SVfrRuleNode (
2287 IN CHAR8 *RuleName,
2288 IN UINT8 RuleId
2289 )
2290 {
2291 if (RuleName != NULL) {
2292 mRuleName = new CHAR8[strlen (RuleName) + 1];
2293 strcpy (mRuleName, RuleName);
2294 } else {
2295 mRuleName = NULL;
2296 }
2297
2298 mNext = NULL;
2299 mRuleId = RuleId;
2300 }
2301
2302 SVfrRuleNode::~SVfrRuleNode (
2303 VOID
2304 )
2305 {
2306 if (mRuleName != NULL) {
2307 delete mRuleName;
2308 }
2309 }
2310
2311 CVfrRulesDB::CVfrRulesDB ()
2312 {
2313 mRuleList = NULL;
2314 mFreeRuleId = EFI_VARSTORE_ID_START;
2315 }
2316
2317 CVfrRulesDB::~CVfrRulesDB ()
2318 {
2319 SVfrRuleNode *pNode;
2320
2321 while(mRuleList != NULL) {
2322 pNode = mRuleList;
2323 mRuleList = mRuleList->mNext;
2324 delete pNode;
2325 }
2326 }
2327
2328 VOID
2329 CVfrRulesDB::RegisterRule (
2330 IN CHAR8 *RuleName
2331 )
2332 {
2333 SVfrRuleNode *pNew;
2334
2335 if (RuleName == NULL) {
2336 return ;
2337 }
2338
2339 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2340 return ;
2341 }
2342
2343 mFreeRuleId++;
2344
2345 pNew->mNext = mRuleList;
2346 mRuleList = pNew;
2347 }
2348
2349 UINT8
2350 CVfrRulesDB::GetRuleId (
2351 IN CHAR8 *RuleName
2352 )
2353 {
2354 SVfrRuleNode *pNode;
2355
2356 if (RuleName == NULL) {
2357 return EFI_RULE_ID_INVALID;
2358 }
2359
2360 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2361 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2362 return pNode->mRuleId;
2363 }
2364 }
2365
2366 return EFI_RULE_ID_INVALID;
2367 }
2368
2369 CVfrRulesDB gCVfrRulesDB;
2370
2371 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2372 VOID
2373 )
2374 {
2375 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2376 mInfo.mVarName = EFI_STRING_ID_INVALID;
2377 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2378 mVarType = EFI_IFR_TYPE_OTHER;
2379 mVarTotalSize = 0;
2380 }
2381
2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2383 IN EFI_VARSTORE_INFO &Info
2384 )
2385 {
2386 mVarStoreId = Info.mVarStoreId;
2387 mInfo.mVarName = Info.mInfo.mVarName;
2388 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2389 mVarType = Info.mVarType;
2390 mVarTotalSize = Info.mVarTotalSize;
2391 }
2392
2393 BOOLEAN
2394 EFI_VARSTORE_INFO::operator == (
2395 IN EFI_VARSTORE_INFO *Info
2396 )
2397 {
2398 if ((mVarStoreId == Info->mVarStoreId) &&
2399 (mInfo.mVarName == Info->mInfo.mVarName) &&
2400 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2401 (mVarType == Info->mVarType) &&
2402 (mVarTotalSize == Info->mVarTotalSize)) {
2403 return TRUE;
2404 }
2405
2406 return FALSE;
2407 }
2408
2409 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2410 IN EFI_VARSTORE_INFO *Info
2411 )
2412 {
2413 mVarStoreInfo.mVarType = Info->mVarType;
2414 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
2415 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
2416 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
2417 mNext = NULL;
2418 }
2419
2420 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2421 {
2422 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
2423 mVarStoreInfo.mVarTotalSize = 0;
2424 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2425 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
2426 mNext = NULL;
2427 }
2428
2429 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2430
2431 EFI_QUESTION_ID
2432 CVfrQuestionDB::GetFreeQuestionId (
2433 VOID
2434 )
2435 {
2436 UINT32 Index, Mask, Offset;
2437
2438 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2439 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2440 break;
2441 }
2442 }
2443
2444 if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
2445 return EFI_QUESTION_ID_INVALID;
2446 }
2447
2448 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2449 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2450 mFreeQIdBitMap[Index] |= Mask;
2451 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2452 }
2453 }
2454
2455 return EFI_QUESTION_ID_INVALID;
2456 }
2457
2458 BOOLEAN
2459 CVfrQuestionDB::ChekQuestionIdFree (
2460 IN EFI_QUESTION_ID QId
2461 )
2462 {
2463 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2464 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2465
2466 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2467 }
2468
2469 VOID
2470 CVfrQuestionDB::MarkQuestionIdUsed (
2471 IN EFI_QUESTION_ID QId
2472 )
2473 {
2474 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2475 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2476
2477 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2478 }
2479
2480 VOID
2481 CVfrQuestionDB::MarkQuestionIdUnused (
2482 IN EFI_QUESTION_ID QId
2483 )
2484 {
2485 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2486 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2487
2488 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2489 }
2490
2491 SVfrQuestionNode::SVfrQuestionNode (
2492 IN CHAR8 *Name,
2493 IN CHAR8 *VarIdStr,
2494 IN UINT32 BitMask
2495 )
2496 {
2497 mName = NULL;
2498 mVarIdStr = NULL;
2499 mQuestionId = EFI_QUESTION_ID_INVALID;
2500 mBitMask = BitMask;
2501 mNext = NULL;
2502 mQtype = QUESTION_NORMAL;
2503
2504 if (Name == NULL) {
2505 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2506 strcpy (mName, "$DEFAULT");
2507 } else {
2508 mName = new CHAR8[strlen (Name) + 1];
2509 strcpy (mName, Name);
2510 }
2511
2512 if (VarIdStr != NULL) {
2513 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2514 strcpy (mVarIdStr, VarIdStr);
2515 } else {
2516 mVarIdStr = new CHAR8[strlen ("$") + 1];
2517 strcpy (mVarIdStr, "$");
2518 }
2519 }
2520
2521 SVfrQuestionNode::~SVfrQuestionNode (
2522 VOID
2523 )
2524 {
2525 if (mName != NULL) {
2526 delete mName;
2527 }
2528
2529 if (mVarIdStr != NULL) {
2530 delete mVarIdStr;
2531 }
2532 }
2533
2534 CVfrQuestionDB::CVfrQuestionDB ()
2535 {
2536 UINT32 Index;
2537
2538 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2539 mFreeQIdBitMap[Index] = 0;
2540 }
2541
2542 // Question ID 0 is reserved.
2543 mFreeQIdBitMap[0] = 0x80000000;
2544 mQuestionList = NULL;
2545 }
2546
2547 CVfrQuestionDB::~CVfrQuestionDB ()
2548 {
2549 SVfrQuestionNode *pNode;
2550
2551 while (mQuestionList != NULL) {
2552 pNode = mQuestionList;
2553 mQuestionList = mQuestionList->mNext;
2554 delete pNode;
2555 }
2556 }
2557
2558 //
2559 // Reset to init state
2560 //
2561 VOID
2562 CVfrQuestionDB::ResetInit(
2563 IN VOID
2564 )
2565 {
2566 UINT32 Index;
2567 SVfrQuestionNode *pNode;
2568
2569 while (mQuestionList != NULL) {
2570 pNode = mQuestionList;
2571 mQuestionList = mQuestionList->mNext;
2572 delete pNode;
2573 }
2574
2575 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2576 mFreeQIdBitMap[Index] = 0;
2577 }
2578
2579 // Question ID 0 is reserved.
2580 mFreeQIdBitMap[0] = 0x80000000;
2581 mQuestionList = NULL;
2582 }
2583
2584 VOID
2585 CVfrQuestionDB::PrintAllQuestion (
2586 VOID
2587 )
2588 {
2589 SVfrQuestionNode *pNode = NULL;
2590
2591 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2592 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2593 }
2594 }
2595
2596 EFI_VFR_RETURN_CODE
2597 CVfrQuestionDB::RegisterQuestion (
2598 IN CHAR8 *Name,
2599 IN CHAR8 *VarIdStr,
2600 IN OUT EFI_QUESTION_ID &QuestionId
2601 )
2602 {
2603 SVfrQuestionNode *pNode = NULL;
2604
2605 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2606 return VFR_RETURN_REDEFINED;
2607 }
2608
2609 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2610 return VFR_RETURN_OUT_FOR_RESOURCES;
2611 }
2612
2613 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2614 QuestionId = GetFreeQuestionId ();
2615 } else {
2616 //
2617 // For Framework Vfr, don't check question ID conflict.
2618 //
2619 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
2620 delete pNode;
2621 return VFR_RETURN_QUESTIONID_REDEFINED;
2622 }
2623 MarkQuestionIdUsed (QuestionId);
2624 }
2625 pNode->mQuestionId = QuestionId;
2626
2627 pNode->mNext = mQuestionList;
2628 mQuestionList = pNode;
2629
2630 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2631
2632 return VFR_RETURN_SUCCESS;
2633 }
2634
2635 VOID
2636 CVfrQuestionDB::RegisterOldDateQuestion (
2637 IN CHAR8 *YearVarId,
2638 IN CHAR8 *MonthVarId,
2639 IN CHAR8 *DayVarId,
2640 IN OUT EFI_QUESTION_ID &QuestionId
2641 )
2642 {
2643 SVfrQuestionNode *pNode[3] = {NULL, };
2644 UINT32 Index;
2645
2646 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2647 return;
2648 }
2649
2650 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2651 goto Err;
2652 }
2653 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2654 goto Err;
2655 }
2656 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2657 goto Err;
2658 }
2659
2660 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2661 QuestionId = GetFreeQuestionId ();
2662 } else {
2663 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2664 goto Err;
2665 }
2666 MarkQuestionIdUsed (QuestionId);
2667 }
2668
2669 pNode[0]->mQuestionId = QuestionId;
2670 pNode[1]->mQuestionId = QuestionId;
2671 pNode[2]->mQuestionId = QuestionId;
2672 pNode[0]->mQtype = QUESTION_DATE;
2673 pNode[1]->mQtype = QUESTION_DATE;
2674 pNode[2]->mQtype = QUESTION_DATE;
2675 pNode[0]->mNext = pNode[1];
2676 pNode[1]->mNext = pNode[2];
2677 pNode[2]->mNext = mQuestionList;
2678 mQuestionList = pNode[0];
2679
2680 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2681 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2682 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2683
2684 return;
2685
2686 Err:
2687 for (Index = 0; Index < 3; Index++) {
2688 if (pNode[Index] != NULL) {
2689 delete pNode[Index];
2690 }
2691 }
2692 QuestionId = EFI_QUESTION_ID_INVALID;
2693 }
2694
2695 VOID
2696 CVfrQuestionDB::RegisterNewDateQuestion (
2697 IN CHAR8 *Name,
2698 IN CHAR8 *BaseVarId,
2699 IN OUT EFI_QUESTION_ID &QuestionId
2700 )
2701 {
2702 SVfrQuestionNode *pNode[3] = {NULL, };
2703 UINT32 Len;
2704 CHAR8 *VarIdStr[3] = {NULL, };
2705 CHAR8 Index;
2706
2707 if (BaseVarId == NULL && Name == NULL) {
2708 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2709 QuestionId = GetFreeQuestionId ();
2710 } else {
2711 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2712 goto Err;
2713 }
2714 MarkQuestionIdUsed (QuestionId);
2715 }
2716 return;
2717 }
2718
2719 if (BaseVarId != NULL) {
2720 Len = strlen (BaseVarId);
2721
2722 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2723 if (VarIdStr[0] != NULL) {
2724 strcpy (VarIdStr[0], BaseVarId);
2725 strcat (VarIdStr[0], ".Year");
2726 }
2727 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2728 if (VarIdStr[1] != NULL) {
2729 strcpy (VarIdStr[1], BaseVarId);
2730 strcat (VarIdStr[1], ".Month");
2731 }
2732 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2733 if (VarIdStr[2] != NULL) {
2734 strcpy (VarIdStr[2], BaseVarId);
2735 strcat (VarIdStr[2], ".Day");
2736 }
2737 } else {
2738 Len = strlen (Name);
2739
2740 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2741 if (VarIdStr[0] != NULL) {
2742 strcpy (VarIdStr[0], Name);
2743 strcat (VarIdStr[0], ".Year");
2744 }
2745 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2746 if (VarIdStr[1] != NULL) {
2747 strcpy (VarIdStr[1], Name);
2748 strcat (VarIdStr[1], ".Month");
2749 }
2750 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2751 if (VarIdStr[2] != NULL) {
2752 strcpy (VarIdStr[2], Name);
2753 strcat (VarIdStr[2], ".Day");
2754 }
2755 }
2756
2757 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2758 goto Err;
2759 }
2760 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2761 goto Err;
2762 }
2763 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2764 goto Err;
2765 }
2766
2767 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2768 QuestionId = GetFreeQuestionId ();
2769 } else {
2770 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2771 goto Err;
2772 }
2773 MarkQuestionIdUsed (QuestionId);
2774 }
2775
2776 pNode[0]->mQuestionId = QuestionId;
2777 pNode[1]->mQuestionId = QuestionId;
2778 pNode[2]->mQuestionId = QuestionId;
2779 pNode[0]->mQtype = QUESTION_DATE;
2780 pNode[1]->mQtype = QUESTION_DATE;
2781 pNode[2]->mQtype = QUESTION_DATE;
2782 pNode[0]->mNext = pNode[1];
2783 pNode[1]->mNext = pNode[2];
2784 pNode[2]->mNext = mQuestionList;
2785 mQuestionList = pNode[0];
2786
2787 for (Index = 0; Index < 3; Index++) {
2788 if (VarIdStr[Index] != NULL) {
2789 delete VarIdStr[Index];
2790 }
2791 }
2792
2793 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2794 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2795 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2796
2797 return;
2798
2799 Err:
2800 for (Index = 0; Index < 3; Index++) {
2801 if (pNode[Index] != NULL) {
2802 delete pNode[Index];
2803 }
2804
2805 if (VarIdStr[Index] != NULL) {
2806 delete VarIdStr[Index];
2807 }
2808 }
2809 }
2810
2811 VOID
2812 CVfrQuestionDB::RegisterOldTimeQuestion (
2813 IN CHAR8 *HourVarId,
2814 IN CHAR8 *MinuteVarId,
2815 IN CHAR8 *SecondVarId,
2816 IN OUT EFI_QUESTION_ID &QuestionId
2817 )
2818 {
2819 SVfrQuestionNode *pNode[3] = {NULL, };
2820 UINT32 Index;
2821
2822 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
2823 return;
2824 }
2825
2826 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
2827 goto Err;
2828 }
2829 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
2830 goto Err;
2831 }
2832 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
2833 goto Err;
2834 }
2835
2836 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2837 QuestionId = GetFreeQuestionId ();
2838 } else {
2839 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2840 goto Err;
2841 }
2842 MarkQuestionIdUsed (QuestionId);
2843 }
2844
2845 pNode[0]->mQuestionId = QuestionId;
2846 pNode[1]->mQuestionId = QuestionId;
2847 pNode[2]->mQuestionId = QuestionId;
2848 pNode[0]->mQtype = QUESTION_TIME;
2849 pNode[1]->mQtype = QUESTION_TIME;
2850 pNode[2]->mQtype = QUESTION_TIME;
2851 pNode[0]->mNext = pNode[1];
2852 pNode[1]->mNext = pNode[2];
2853 pNode[2]->mNext = mQuestionList;
2854 mQuestionList = pNode[0];
2855
2856 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2857 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2858 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2859
2860 return;
2861
2862 Err:
2863 for (Index = 0; Index < 3; Index++) {
2864 if (pNode[Index] != NULL) {
2865 delete pNode[Index];
2866 }
2867 }
2868 QuestionId = EFI_QUESTION_ID_INVALID;
2869 }
2870
2871 VOID
2872 CVfrQuestionDB::RegisterNewTimeQuestion (
2873 IN CHAR8 *Name,
2874 IN CHAR8 *BaseVarId,
2875 IN OUT EFI_QUESTION_ID &QuestionId
2876 )
2877 {
2878 SVfrQuestionNode *pNode[3] = {NULL, };
2879 UINT32 Len;
2880 CHAR8 *VarIdStr[3] = {NULL, };
2881 CHAR8 Index;
2882
2883 if (BaseVarId == NULL && Name == NULL) {
2884 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2885 QuestionId = GetFreeQuestionId ();
2886 } else {
2887 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2888 goto Err;
2889 }
2890 MarkQuestionIdUsed (QuestionId);
2891 }
2892 return;
2893 }
2894
2895 if (BaseVarId != NULL) {
2896 Len = strlen (BaseVarId);
2897
2898 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2899 if (VarIdStr[0] != NULL) {
2900 strcpy (VarIdStr[0], BaseVarId);
2901 strcat (VarIdStr[0], ".Hour");
2902 }
2903 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2904 if (VarIdStr[1] != NULL) {
2905 strcpy (VarIdStr[1], BaseVarId);
2906 strcat (VarIdStr[1], ".Minute");
2907 }
2908 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2909 if (VarIdStr[2] != NULL) {
2910 strcpy (VarIdStr[2], BaseVarId);
2911 strcat (VarIdStr[2], ".Second");
2912 }
2913 } else {
2914 Len = strlen (Name);
2915
2916 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2917 if (VarIdStr[0] != NULL) {
2918 strcpy (VarIdStr[0], Name);
2919 strcat (VarIdStr[0], ".Hour");
2920 }
2921 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2922 if (VarIdStr[1] != NULL) {
2923 strcpy (VarIdStr[1], Name);
2924 strcat (VarIdStr[1], ".Minute");
2925 }
2926 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2927 if (VarIdStr[2] != NULL) {
2928 strcpy (VarIdStr[2], Name);
2929 strcat (VarIdStr[2], ".Second");
2930 }
2931 }
2932
2933 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
2934 goto Err;
2935 }
2936 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
2937 goto Err;
2938 }
2939 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
2940 goto Err;
2941 }
2942
2943 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2944 QuestionId = GetFreeQuestionId ();
2945 } else {
2946 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2947 goto Err;
2948 }
2949 MarkQuestionIdUsed (QuestionId);
2950 }
2951
2952 pNode[0]->mQuestionId = QuestionId;
2953 pNode[1]->mQuestionId = QuestionId;
2954 pNode[2]->mQuestionId = QuestionId;
2955 pNode[0]->mQtype = QUESTION_TIME;
2956 pNode[1]->mQtype = QUESTION_TIME;
2957 pNode[2]->mQtype = QUESTION_TIME;
2958 pNode[0]->mNext = pNode[1];
2959 pNode[1]->mNext = pNode[2];
2960 pNode[2]->mNext = mQuestionList;
2961 mQuestionList = pNode[0];
2962
2963 for (Index = 0; Index < 3; Index++) {
2964 if (VarIdStr[Index] != NULL) {
2965 delete VarIdStr[Index];
2966 }
2967 }
2968
2969 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2970 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2971 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2972
2973 return;
2974
2975 Err:
2976 for (Index = 0; Index < 3; Index++) {
2977 if (pNode[Index] != NULL) {
2978 delete pNode[Index];
2979 }
2980
2981 if (VarIdStr[Index] != NULL) {
2982 delete VarIdStr[Index];
2983 }
2984 }
2985 }
2986
2987 VOID
2988 CVfrQuestionDB::RegisterRefQuestion (
2989 IN CHAR8 *Name,
2990 IN CHAR8 *BaseVarId,
2991 IN OUT EFI_QUESTION_ID &QuestionId
2992 )
2993 {
2994 SVfrQuestionNode *pNode[4] = {NULL, };
2995 UINT32 Len;
2996 CHAR8 *VarIdStr[4] = {NULL, };
2997 CHAR8 Index;
2998
2999 if (BaseVarId == NULL && Name == NULL) {
3000 return;
3001 }
3002
3003 if (BaseVarId != NULL) {
3004 Len = strlen (BaseVarId);
3005
3006 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3007 if (VarIdStr[0] != NULL) {
3008 strcpy (VarIdStr[0], BaseVarId);
3009 strcat (VarIdStr[0], ".QuestionId");
3010 }
3011 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3012 if (VarIdStr[1] != NULL) {
3013 strcpy (VarIdStr[1], BaseVarId);
3014 strcat (VarIdStr[1], ".FormId");
3015 }
3016 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3017 if (VarIdStr[2] != NULL) {
3018 strcpy (VarIdStr[2], BaseVarId);
3019 strcat (VarIdStr[2], ".FormSetGuid");
3020 }
3021 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3022 if (VarIdStr[3] != NULL) {
3023 strcpy (VarIdStr[3], BaseVarId);
3024 strcat (VarIdStr[3], ".DevicePath");
3025 }
3026 } else {
3027 Len = strlen (Name);
3028
3029 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3030 if (VarIdStr[0] != NULL) {
3031 strcpy (VarIdStr[0], Name);
3032 strcat (VarIdStr[0], ".QuestionId");
3033 }
3034 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3035 if (VarIdStr[1] != NULL) {
3036 strcpy (VarIdStr[1], Name);
3037 strcat (VarIdStr[1], ".FormId");
3038 }
3039 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3040 if (VarIdStr[2] != NULL) {
3041 strcpy (VarIdStr[2], Name);
3042 strcat (VarIdStr[2], ".FormSetGuid");
3043 }
3044 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3045 if (VarIdStr[3] != NULL) {
3046 strcpy (VarIdStr[3], Name);
3047 strcat (VarIdStr[3], ".DevicePath");
3048 }
3049 }
3050
3051 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
3052 goto Err;
3053 }
3054 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
3055 goto Err;
3056 }
3057 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
3058 goto Err;
3059 }
3060 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
3061 goto Err;
3062 }
3063
3064 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3065 QuestionId = GetFreeQuestionId ();
3066 } else {
3067 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3068 goto Err;
3069 }
3070 MarkQuestionIdUsed (QuestionId);
3071 }
3072
3073 pNode[0]->mQuestionId = QuestionId;
3074 pNode[1]->mQuestionId = QuestionId;
3075 pNode[2]->mQuestionId = QuestionId;
3076 pNode[3]->mQuestionId = QuestionId;
3077 pNode[0]->mQtype = QUESTION_REF;
3078 pNode[1]->mQtype = QUESTION_REF;
3079 pNode[2]->mQtype = QUESTION_REF;
3080 pNode[3]->mQtype = QUESTION_REF;
3081 pNode[0]->mNext = pNode[1];
3082 pNode[1]->mNext = pNode[2];
3083 pNode[2]->mNext = pNode[3];
3084 pNode[3]->mNext = mQuestionList;
3085 mQuestionList = pNode[0];
3086
3087 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3088 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3089 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3090 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3091
3092 return;
3093
3094 Err:
3095 for (Index = 0; Index < 4; Index++) {
3096 if (pNode[Index] != NULL) {
3097 delete pNode[Index];
3098 }
3099
3100 if (VarIdStr[Index] != NULL) {
3101 delete VarIdStr[Index];
3102 }
3103 }
3104 }
3105
3106 EFI_VFR_RETURN_CODE
3107 CVfrQuestionDB::UpdateQuestionId (
3108 IN EFI_QUESTION_ID QId,
3109 IN EFI_QUESTION_ID NewQId
3110 )
3111 {
3112 SVfrQuestionNode *pNode = NULL;
3113
3114 if (QId == NewQId) {
3115 // don't update
3116 return VFR_RETURN_SUCCESS;
3117 }
3118
3119 //
3120 // For Framework Vfr, don't check question ID conflict.
3121 //
3122 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
3123 return VFR_RETURN_REDEFINED;
3124 }
3125
3126 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3127 if (pNode->mQuestionId == QId) {
3128 break;
3129 }
3130 }
3131
3132 if (pNode == NULL) {
3133 return VFR_RETURN_UNDEFINED;
3134 }
3135
3136 MarkQuestionIdUnused (QId);
3137 pNode->mQuestionId = NewQId;
3138 MarkQuestionIdUsed (NewQId);
3139
3140 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
3141
3142 return VFR_RETURN_SUCCESS;
3143 }
3144
3145 VOID
3146 CVfrQuestionDB::GetQuestionId (
3147 IN CHAR8 *Name,
3148 IN CHAR8 *VarIdStr,
3149 OUT EFI_QUESTION_ID &QuestionId,
3150 OUT UINT32 &BitMask,
3151 OUT EFI_QUESION_TYPE *QType
3152 )
3153 {
3154 SVfrQuestionNode *pNode;
3155
3156 QuestionId = EFI_QUESTION_ID_INVALID;
3157 BitMask = 0x00000000;
3158 if (QType != NULL) {
3159 *QType = QUESTION_NORMAL;
3160 }
3161
3162 if ((Name == NULL) && (VarIdStr == NULL)) {
3163 return ;
3164 }
3165
3166 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3167 if (Name != NULL) {
3168 if (strcmp (pNode->mName, Name) != 0) {
3169 continue;
3170 }
3171 }
3172
3173 if (VarIdStr != NULL) {
3174 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
3175 continue;
3176 }
3177 }
3178
3179 QuestionId = pNode->mQuestionId;
3180 BitMask = pNode->mBitMask;
3181 if (QType != NULL) {
3182 *QType = pNode->mQtype;
3183 }
3184 break;
3185 }
3186
3187 return ;
3188 }
3189
3190 EFI_VFR_RETURN_CODE
3191 CVfrQuestionDB::FindQuestion (
3192 IN EFI_QUESTION_ID QuestionId
3193 )
3194 {
3195 SVfrQuestionNode *pNode;
3196
3197 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3198 return VFR_RETURN_INVALID_PARAMETER;
3199 }
3200
3201 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3202 if (pNode->mQuestionId == QuestionId) {
3203 return VFR_RETURN_SUCCESS;
3204 }
3205 }
3206
3207 return VFR_RETURN_UNDEFINED;
3208 }
3209
3210 EFI_VFR_RETURN_CODE
3211 CVfrQuestionDB::FindQuestion (
3212 IN CHAR8 *Name
3213 )
3214 {
3215 SVfrQuestionNode *pNode;
3216
3217 if (Name == NULL) {
3218 return VFR_RETURN_FATAL_ERROR;
3219 }
3220
3221 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3222 if (strcmp (pNode->mName, Name) == 0) {
3223 return VFR_RETURN_SUCCESS;
3224 }
3225 }
3226
3227 return VFR_RETURN_UNDEFINED;
3228 }
3229
3230 CVfrStringDB::CVfrStringDB ()
3231 {
3232 mStringFileName = NULL;
3233 }
3234
3235 CVfrStringDB::~CVfrStringDB ()
3236 {
3237 if (mStringFileName != NULL) {
3238 delete mStringFileName;
3239 }
3240 mStringFileName = NULL;
3241 }
3242
3243
3244 VOID
3245 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
3246 {
3247 UINT32 FileLen = 0;
3248
3249 if (StringFileName == NULL) {
3250 return;
3251 }
3252
3253 FileLen = strlen (StringFileName) + 1;
3254 mStringFileName = new CHAR8[FileLen];
3255 if (mStringFileName == NULL) {
3256 return;
3257 }
3258
3259 strcpy (mStringFileName, StringFileName);
3260 mStringFileName[FileLen - 1] = '\0';
3261 }
3262
3263
3264 /**
3265 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3266 from a set of supported languages.
3267
3268 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3269 contains a set of language codes.
3270 @param[in] Language A variable that contains pointers to Null-terminated
3271 ASCII strings that contain one language codes.
3272
3273 @retval FALSE The best matching language could not be found in SupportedLanguages.
3274 @retval TRUE The best matching language could be found in SupportedLanguages.
3275
3276 **/
3277 BOOLEAN
3278 CVfrStringDB::GetBestLanguage (
3279 IN CONST CHAR8 *SupportedLanguages,
3280 IN CHAR8 *Language
3281 )
3282 {
3283 UINTN CompareLength;
3284 UINTN LanguageLength;
3285 CONST CHAR8 *Supported;
3286
3287 if (SupportedLanguages == NULL || Language == NULL){
3288 return FALSE;
3289 }
3290
3291 //
3292 // Determine the length of the first RFC 4646 language code in Language
3293 //
3294 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
3295
3296 //
3297 // Trim back the length of Language used until it is empty
3298 //
3299 while (LanguageLength > 0) {
3300 //
3301 // Loop through all language codes in SupportedLanguages
3302 //
3303 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
3304 //
3305 // Skip ';' characters in Supported
3306 //
3307 for (; *Supported != '\0' && *Supported == ';'; Supported++);
3308 //
3309 // Determine the length of the next language code in Supported
3310 //
3311 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
3312 //
3313 // If Language is longer than the Supported, then skip to the next language
3314 //
3315 if (LanguageLength > CompareLength) {
3316 continue;
3317 }
3318
3319 //
3320 // See if the first LanguageLength characters in Supported match Language
3321 //
3322 if (strncmp (Supported, Language, LanguageLength) == 0) {
3323 return TRUE;
3324 }
3325 }
3326
3327 //
3328 // Trim Language from the right to the next '-' character
3329 //
3330 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
3331 }
3332
3333 //
3334 // No matches were found
3335 //
3336 return FALSE;
3337 }
3338
3339
3340 CHAR8 *
3341 CVfrStringDB::GetVarStoreNameFormStringId (
3342 IN EFI_STRING_ID StringId
3343 )
3344 {
3345 FILE *pInFile = NULL;
3346 UINT32 NameOffset;
3347 UINT32 Length;
3348 UINT8 *StringPtr;
3349 CHAR8 *StringName;
3350 CHAR16 *UnicodeString;
3351 CHAR8 *VarStoreName = NULL;
3352 CHAR8 *DestTmp;
3353 UINT8 *Current;
3354 EFI_STATUS Status;
3355 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
3356 UINT8 BlockType;
3357 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
3358
3359 if (mStringFileName == '\0' ) {
3360 return NULL;
3361 }
3362
3363 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
3364 return NULL;
3365 }
3366
3367 //
3368 // Get file length.
3369 //
3370 fseek (pInFile, 0, SEEK_END);
3371 Length = ftell (pInFile);
3372 fseek (pInFile, 0, SEEK_SET);
3373
3374 //
3375 // Get file data.
3376 //
3377 StringPtr = new UINT8[Length];
3378 if (StringPtr == NULL) {
3379 fclose (pInFile);
3380 return NULL;
3381 }
3382 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
3383 fclose (pInFile);
3384
3385 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3386 //
3387 // Check the String package.
3388 //
3389 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
3390 delete StringPtr;
3391 return NULL;
3392 }
3393
3394 //
3395 // Search the language, get best language base on RFC 4647 matching algorithm.
3396 //
3397 Current = StringPtr;
3398 while (!GetBestLanguage ("en", PkgHeader->Language)) {
3399 Current += PkgHeader->Header.Length;
3400 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
3401 //
3402 // If can't find string package base on language, just return the first string package.
3403 //
3404 if (Current - StringPtr >= Length) {
3405 Current = StringPtr;
3406 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3407 break;
3408 }
3409 }
3410
3411 Current += PkgHeader->HdrSize;
3412 //
3413 // Find the string block according the stringId.
3414 //
3415 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
3416 if (Status != EFI_SUCCESS) {
3417 delete StringPtr;
3418 return NULL;
3419 }
3420
3421 //
3422 // Get varstore name according the string type.
3423 //
3424 switch (BlockType) {
3425 case EFI_HII_SIBT_STRING_SCSU:
3426 case EFI_HII_SIBT_STRING_SCSU_FONT:
3427 case EFI_HII_SIBT_STRINGS_SCSU:
3428 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3429 StringName = (CHAR8*)(Current + NameOffset);
3430 VarStoreName = new CHAR8[strlen(StringName) + 1];
3431 strcpy (VarStoreName, StringName);
3432 break;
3433 case EFI_HII_SIBT_STRING_UCS2:
3434 case EFI_HII_SIBT_STRING_UCS2_FONT:
3435 case EFI_HII_SIBT_STRINGS_UCS2:
3436 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3437 UnicodeString = (CHAR16*)(Current + NameOffset);
3438 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
3439 DestTmp = new CHAR8[Length / 2 + 1];
3440 VarStoreName = DestTmp;
3441 while (*UnicodeString != '\0') {
3442 *(DestTmp++) = (CHAR8) *(UnicodeString++);
3443 }
3444 *DestTmp = '\0';
3445 break;
3446 default:
3447 break;
3448 }
3449
3450 delete StringPtr;
3451
3452 return VarStoreName;
3453 }
3454
3455 EFI_STATUS
3456 CVfrStringDB::FindStringBlock (
3457 IN UINT8 *StringData,
3458 IN EFI_STRING_ID StringId,
3459 OUT UINT32 *StringTextOffset,
3460 OUT UINT8 *BlockType
3461 )
3462 {
3463 UINT8 *BlockHdr;
3464 EFI_STRING_ID CurrentStringId;
3465 UINT32 BlockSize;
3466 UINT32 Index;
3467 UINT8 *StringTextPtr;
3468 UINT32 Offset;
3469 UINT16 StringCount;
3470 UINT16 SkipCount;
3471 UINT8 Length8;
3472 EFI_HII_SIBT_EXT2_BLOCK Ext2;
3473 UINT32 Length32;
3474 UINT32 StringSize;
3475
3476 CurrentStringId = 1;
3477
3478 //
3479 // Parse the string blocks to get the string text and font.
3480 //
3481 BlockHdr = StringData;
3482 BlockSize = 0;
3483 Offset = 0;
3484 while (*BlockHdr != EFI_HII_SIBT_END) {
3485 switch (*BlockHdr) {
3486 case EFI_HII_SIBT_STRING_SCSU:
3487 Offset = sizeof (EFI_HII_STRING_BLOCK);
3488 StringTextPtr = BlockHdr + Offset;
3489 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3490 CurrentStringId++;
3491 break;
3492
3493 case EFI_HII_SIBT_STRING_SCSU_FONT:
3494 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
3495 StringTextPtr = BlockHdr + Offset;
3496 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3497 CurrentStringId++;
3498 break;
3499
3500 case EFI_HII_SIBT_STRINGS_SCSU:
3501 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3502 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
3503 BlockSize += StringTextPtr - BlockHdr;
3504
3505 for (Index = 0; Index < StringCount; Index++) {
3506 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3507 if (CurrentStringId == StringId) {
3508 *BlockType = *BlockHdr;
3509 *StringTextOffset = StringTextPtr - StringData;
3510 return EFI_SUCCESS;
3511 }
3512 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3513 CurrentStringId++;
3514 }
3515 break;
3516
3517 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3518 memcpy (
3519 &StringCount,
3520 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3521 sizeof (UINT16)
3522 );
3523 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
3524 BlockSize += StringTextPtr - BlockHdr;
3525
3526 for (Index = 0; Index < StringCount; Index++) {
3527 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3528 if (CurrentStringId == StringId) {
3529 *BlockType = *BlockHdr;
3530 *StringTextOffset = StringTextPtr - StringData;
3531 return EFI_SUCCESS;
3532 }
3533 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3534 CurrentStringId++;
3535 }
3536 break;
3537
3538 case EFI_HII_SIBT_STRING_UCS2:
3539 Offset = sizeof (EFI_HII_STRING_BLOCK);
3540 StringTextPtr = BlockHdr + Offset;
3541 //
3542 // Use StringSize to store the size of the specified string, including the NULL
3543 // terminator.
3544 //
3545 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3546 BlockSize += Offset + StringSize;
3547 CurrentStringId++;
3548 break;
3549
3550 case EFI_HII_SIBT_STRING_UCS2_FONT:
3551 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3552 StringTextPtr = BlockHdr + Offset;
3553 //
3554 // Use StrSize to store the size of the specified string, including the NULL
3555 // terminator.
3556 //
3557 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3558 BlockSize += Offset + StringSize;
3559 CurrentStringId++;
3560 break;
3561
3562 case EFI_HII_SIBT_STRINGS_UCS2:
3563 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
3564 StringTextPtr = BlockHdr + Offset;
3565 BlockSize += Offset;
3566 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3567 for (Index = 0; Index < StringCount; Index++) {
3568 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3569 BlockSize += StringSize;
3570 if (CurrentStringId == StringId) {
3571 *BlockType = *BlockHdr;
3572 *StringTextOffset = StringTextPtr - StringData;
3573 return EFI_SUCCESS;
3574 }
3575 StringTextPtr = StringTextPtr + StringSize;
3576 CurrentStringId++;
3577 }
3578 break;
3579
3580 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3581 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3582 StringTextPtr = BlockHdr + Offset;
3583 BlockSize += Offset;
3584 memcpy (
3585 &StringCount,
3586 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3587 sizeof (UINT16)
3588 );
3589 for (Index = 0; Index < StringCount; Index++) {
3590 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3591 BlockSize += StringSize;
3592 if (CurrentStringId == StringId) {
3593 *BlockType = *BlockHdr;
3594 *StringTextOffset = StringTextPtr - StringData;
3595 return EFI_SUCCESS;
3596 }
3597 StringTextPtr = StringTextPtr + StringSize;
3598 CurrentStringId++;
3599 }
3600 break;
3601
3602 case EFI_HII_SIBT_DUPLICATE:
3603 if (CurrentStringId == StringId) {
3604 //
3605 // Incoming StringId is an id of a duplicate string block.
3606 // Update the StringId to be the previous string block.
3607 // Go back to the header of string block to search.
3608 //
3609 memcpy (
3610 &StringId,
3611 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
3612 sizeof (EFI_STRING_ID)
3613 );
3614 CurrentStringId = 1;
3615 BlockSize = 0;
3616 } else {
3617 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
3618 CurrentStringId++;
3619 }
3620 break;
3621
3622 case EFI_HII_SIBT_SKIP1:
3623 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
3624 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3625 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
3626 break;
3627
3628 case EFI_HII_SIBT_SKIP2:
3629 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3630 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3631 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
3632 break;
3633
3634 case EFI_HII_SIBT_EXT1:
3635 memcpy (
3636 &Length8,
3637 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3638 sizeof (UINT8)
3639 );
3640 BlockSize += Length8;
3641 break;
3642
3643 case EFI_HII_SIBT_EXT2:
3644 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
3645 BlockSize += Ext2.Length;
3646 break;
3647
3648 case EFI_HII_SIBT_EXT4:
3649 memcpy (
3650 &Length32,
3651 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3652 sizeof (UINT32)
3653 );
3654
3655 BlockSize += Length32;
3656 break;
3657
3658 default:
3659 break;
3660 }
3661
3662 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
3663 *StringTextOffset = BlockHdr - StringData + Offset;
3664 *BlockType = *BlockHdr;
3665
3666 if (StringId == CurrentStringId - 1) {
3667 //
3668 // if only one skip item, return EFI_NOT_FOUND.
3669 //
3670 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
3671 return EFI_NOT_FOUND;
3672 } else {
3673 return EFI_SUCCESS;
3674 }
3675 }
3676
3677 if (StringId < CurrentStringId - 1) {
3678 return EFI_NOT_FOUND;
3679 }
3680 }
3681 BlockHdr = StringData + BlockSize;
3682 }
3683
3684 return EFI_NOT_FOUND;
3685 }
3686
3687 UINT32
3688 CVfrStringDB::GetUnicodeStringTextSize (
3689 IN UINT8 *StringSrc
3690 )
3691 {
3692 UINT32 StringSize;
3693 CHAR16 *StringPtr;
3694
3695 StringSize = sizeof (CHAR16);
3696 StringPtr = (UINT16*)StringSrc;
3697 while (*StringPtr++ != L'\0') {
3698 StringSize += sizeof (CHAR16);
3699 }
3700
3701 return StringSize;
3702 }
3703
3704 BOOLEAN VfrCompatibleMode = FALSE;
3705
3706 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
3707 CVfrDefaultStore gCVfrDefaultStore;
3708 CVfrDataStorage gCVfrDataStorage;
3709
3710