]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools/VfrCompile: Avoid possible NULL pointer dereference
[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 (&Guid, 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 (&Guid, 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 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1478 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1479 mFreeVarStoreIdBitMap[Index] |= Mask;
1480 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1481 }
1482 }
1483
1484 return EFI_VARSTORE_ID_INVALID;
1485 }
1486
1487 BOOLEAN
1488 CVfrDataStorage::ChekVarStoreIdFree (
1489 IN EFI_VARSTORE_ID VarStoreId
1490 )
1491 {
1492 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1493 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1494
1495 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1496 }
1497
1498 VOID
1499 CVfrDataStorage::MarkVarStoreIdUsed (
1500 IN EFI_VARSTORE_ID VarStoreId
1501 )
1502 {
1503 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1504 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1505
1506 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1507 }
1508
1509 VOID
1510 CVfrDataStorage::MarkVarStoreIdUnused (
1511 IN EFI_VARSTORE_ID VarStoreId
1512 )
1513 {
1514 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1515 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1516
1517 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1518 }
1519
1520 EFI_VFR_RETURN_CODE
1521 CVfrDataStorage::DeclareNameVarStoreBegin (
1522 IN CHAR8 *StoreName,
1523 IN EFI_VARSTORE_ID VarStoreId
1524 )
1525 {
1526 SVfrVarStorageNode *pNode = NULL;
1527 EFI_VARSTORE_ID TmpVarStoreId;
1528
1529 if (StoreName == NULL) {
1530 return VFR_RETURN_FATAL_ERROR;
1531 }
1532
1533 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
1534 return VFR_RETURN_REDEFINED;
1535 }
1536
1537 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1538 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1539 } else {
1540 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1541 return VFR_RETURN_VARSTOREID_REDEFINED;
1542 }
1543 MarkVarStoreIdUsed (VarStoreId);
1544 }
1545
1546 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1547 return VFR_RETURN_UNDEFINED;
1548 }
1549
1550 mNewVarStorageNode = pNode;
1551
1552 return VFR_RETURN_SUCCESS;
1553 }
1554
1555 EFI_VFR_RETURN_CODE
1556 CVfrDataStorage::NameTableAddItem (
1557 IN EFI_STRING_ID Item
1558 )
1559 {
1560 EFI_VARSTORE_ID *NewTable, *OldTable;
1561 UINT32 TableSize;
1562
1563 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1564 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1565
1566 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1567 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1568 return VFR_RETURN_OUT_FOR_RESOURCES;
1569 }
1570 memcpy (NewTable, OldTable, TableSize);
1571 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1572 }
1573
1574 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1575 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1576
1577 return VFR_RETURN_SUCCESS;
1578 }
1579
1580 EFI_VFR_RETURN_CODE
1581 CVfrDataStorage::DeclareNameVarStoreEnd (
1582 IN EFI_GUID *Guid
1583 )
1584 {
1585 mNewVarStorageNode->mGuid = *Guid;
1586 mNewVarStorageNode->mNext = mNameVarStoreList;
1587 mNameVarStoreList = mNewVarStorageNode;
1588
1589 mNewVarStorageNode = NULL;
1590
1591 return VFR_RETURN_SUCCESS;
1592 }
1593
1594 EFI_VFR_RETURN_CODE
1595 CVfrDataStorage::DeclareEfiVarStore (
1596 IN CHAR8 *StoreName,
1597 IN EFI_GUID *Guid,
1598 IN EFI_STRING_ID NameStrId,
1599 IN UINT32 VarSize,
1600 IN BOOLEAN Flag
1601 )
1602 {
1603 SVfrVarStorageNode *pNode;
1604 EFI_VARSTORE_ID VarStoreId;
1605
1606 if ((StoreName == NULL) || (Guid == NULL)) {
1607 return VFR_RETURN_FATAL_ERROR;
1608 }
1609
1610 if (VarSize > sizeof (UINT64)) {
1611 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1612 }
1613
1614 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1615 return VFR_RETURN_REDEFINED;
1616 }
1617
1618 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
1619 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
1620 return VFR_RETURN_OUT_FOR_RESOURCES;
1621 }
1622
1623 pNode->mNext = mEfiVarStoreList;
1624 mEfiVarStoreList = pNode;
1625
1626 return VFR_RETURN_SUCCESS;
1627 }
1628
1629 EFI_VFR_RETURN_CODE
1630 CVfrDataStorage::DeclareBufferVarStore (
1631 IN CHAR8 *StoreName,
1632 IN EFI_GUID *Guid,
1633 IN CVfrVarDataTypeDB *DataTypeDB,
1634 IN CHAR8 *TypeName,
1635 IN EFI_VARSTORE_ID VarStoreId,
1636 IN BOOLEAN Flag
1637 )
1638 {
1639 SVfrVarStorageNode *pNew = NULL;
1640 SVfrDataType *pDataType = NULL;
1641 EFI_VARSTORE_ID TempVarStoreId;
1642
1643 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1644 return VFR_RETURN_FATAL_ERROR;
1645 }
1646
1647 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1648 return VFR_RETURN_REDEFINED;
1649 }
1650
1651 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1652
1653 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1654 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1655 } else {
1656 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1657 return VFR_RETURN_VARSTOREID_REDEFINED;
1658 }
1659 MarkVarStoreIdUsed (VarStoreId);
1660 }
1661
1662 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
1663 return VFR_RETURN_OUT_FOR_RESOURCES;
1664 }
1665
1666 pNew->mNext = mBufferVarStoreList;
1667 mBufferVarStoreList = pNew;
1668
1669 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
1670 return VFR_RETURN_FATAL_ERROR;
1671 }
1672
1673 return VFR_RETURN_SUCCESS;
1674 }
1675
1676 EFI_VFR_RETURN_CODE
1677 CVfrDataStorage::GetVarStoreByDataType (
1678 IN CHAR8 *DataTypeName,
1679 OUT SVfrVarStorageNode **VarNode,
1680 IN EFI_GUID *VarGuid
1681 )
1682 {
1683 SVfrVarStorageNode *pNode;
1684 SVfrVarStorageNode *MatchNode;
1685
1686 //
1687 // Framework VFR uses Data type name as varstore name, so don't need check again.
1688 //
1689 if (VfrCompatibleMode) {
1690 return VFR_RETURN_UNDEFINED;
1691 }
1692
1693 MatchNode = NULL;
1694 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1695 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
1696 continue;
1697 }
1698
1699 if ((VarGuid != NULL)) {
1700 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1701 *VarNode = pNode;
1702 return VFR_RETURN_SUCCESS;
1703 }
1704 } else {
1705 if (MatchNode == NULL) {
1706 MatchNode = pNode;
1707 } else {
1708 //
1709 // More than one varstores referred the same data structures.
1710 //
1711 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
1712 }
1713 }
1714 }
1715
1716 if (MatchNode == NULL) {
1717 return VFR_RETURN_UNDEFINED;
1718 }
1719
1720 *VarNode = MatchNode;
1721 return VFR_RETURN_SUCCESS;
1722 }
1723
1724 EFI_VARSTORE_ID
1725 CVfrDataStorage::CheckGuidField (
1726 IN SVfrVarStorageNode *pNode,
1727 IN EFI_GUID *StoreGuid,
1728 IN BOOLEAN *HasFoundOne,
1729 OUT EFI_VFR_RETURN_CODE *ReturnCode
1730 )
1731 {
1732 if (StoreGuid != NULL) {
1733 //
1734 // If has guid info, compare the guid filed.
1735 //
1736 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1737 //
1738 // Both name and guid are same, this this varstore.
1739 //
1740 mCurrVarStorageNode = pNode;
1741 *ReturnCode = VFR_RETURN_SUCCESS;
1742 return TRUE;
1743 }
1744 } else {
1745 //
1746 // Not has Guid field, check whether this name is the only one.
1747 //
1748 if (*HasFoundOne) {
1749 //
1750 // The name has conflict, return name redefined.
1751 //
1752 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
1753 return TRUE;
1754 }
1755
1756 *HasFoundOne = TRUE;
1757 mCurrVarStorageNode = pNode;
1758 }
1759
1760 return FALSE;
1761 }
1762
1763 /**
1764 Base on the input store name and guid to find the varstore id.
1765
1766 If both name and guid are inputed, base on the name and guid to
1767 found the varstore. If only name inputed, base on the name to
1768 found the varstore and go on to check whether more than one varstore
1769 has the same name. If only has found one varstore, return this
1770 varstore; if more than one varstore has same name, return varstore
1771 name redefined error. If no varstore found by varstore name, call
1772 function GetVarStoreByDataType and use inputed varstore name as
1773 data type name to search.
1774 **/
1775 EFI_VFR_RETURN_CODE
1776 CVfrDataStorage::GetVarStoreId (
1777 IN CHAR8 *StoreName,
1778 OUT EFI_VARSTORE_ID *VarStoreId,
1779 IN EFI_GUID *StoreGuid
1780 )
1781 {
1782 EFI_VFR_RETURN_CODE ReturnCode;
1783 SVfrVarStorageNode *pNode;
1784 BOOLEAN HasFoundOne = FALSE;
1785
1786 mCurrVarStorageNode = NULL;
1787
1788 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1789 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1790 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1791 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1792 return ReturnCode;
1793 }
1794 }
1795 }
1796
1797 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1798 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1799 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1800 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1801 return ReturnCode;
1802 }
1803 }
1804 }
1805
1806 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1807 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1808 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1809 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1810 return ReturnCode;
1811 }
1812 }
1813 }
1814
1815 if (HasFoundOne) {
1816 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1817 return VFR_RETURN_SUCCESS;
1818 }
1819
1820 *VarStoreId = EFI_VARSTORE_ID_INVALID;
1821
1822 //
1823 // Assume that Data strucutre name is used as StoreName, and check again.
1824 //
1825 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
1826 if (pNode != NULL) {
1827 mCurrVarStorageNode = pNode;
1828 *VarStoreId = pNode->mVarStoreId;
1829 }
1830
1831 return ReturnCode;
1832 }
1833
1834 EFI_VFR_RETURN_CODE
1835 CVfrDataStorage::GetBufferVarStoreDataTypeName (
1836 IN EFI_VARSTORE_ID VarStoreId,
1837 OUT CHAR8 **DataTypeName
1838 )
1839 {
1840 SVfrVarStorageNode *pNode;
1841
1842 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1843 return VFR_RETURN_FATAL_ERROR;
1844 }
1845
1846 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1847 if (pNode->mVarStoreId == VarStoreId) {
1848 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
1849 return VFR_RETURN_SUCCESS;
1850 }
1851 }
1852
1853 return VFR_RETURN_UNDEFINED;
1854 }
1855
1856 EFI_VFR_VARSTORE_TYPE
1857 CVfrDataStorage::GetVarStoreType (
1858 IN EFI_VARSTORE_ID VarStoreId
1859 )
1860 {
1861 SVfrVarStorageNode *pNode;
1862 EFI_VFR_VARSTORE_TYPE VarStoreType;
1863
1864 VarStoreType = EFI_VFR_VARSTORE_INVALID;
1865
1866 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1867 return VarStoreType;
1868 }
1869
1870 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1871 if (pNode->mVarStoreId == VarStoreId) {
1872 VarStoreType = pNode->mVarStoreType;
1873 return VarStoreType;
1874 }
1875 }
1876
1877 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1878 if (pNode->mVarStoreId == VarStoreId) {
1879 VarStoreType = pNode->mVarStoreType;
1880 return VarStoreType;
1881 }
1882 }
1883
1884 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1885 if (pNode->mVarStoreId == VarStoreId) {
1886 VarStoreType = pNode->mVarStoreType;
1887 return VarStoreType;
1888 }
1889 }
1890
1891 return VarStoreType;
1892 }
1893
1894 EFI_GUID *
1895 CVfrDataStorage::GetVarStoreGuid (
1896 IN EFI_VARSTORE_ID VarStoreId
1897 )
1898 {
1899 SVfrVarStorageNode *pNode;
1900 EFI_GUID *VarGuid;
1901
1902 VarGuid = NULL;
1903
1904 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1905 return VarGuid;
1906 }
1907
1908 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1909 if (pNode->mVarStoreId == VarStoreId) {
1910 VarGuid = &pNode->mGuid;
1911 return VarGuid;
1912 }
1913 }
1914
1915 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1916 if (pNode->mVarStoreId == VarStoreId) {
1917 VarGuid = &pNode->mGuid;
1918 return VarGuid;
1919 }
1920 }
1921
1922 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1923 if (pNode->mVarStoreId == VarStoreId) {
1924 VarGuid = &pNode->mGuid;
1925 return VarGuid;
1926 }
1927 }
1928
1929 return VarGuid;
1930 }
1931
1932 EFI_VFR_RETURN_CODE
1933 CVfrDataStorage::GetVarStoreName (
1934 IN EFI_VARSTORE_ID VarStoreId,
1935 OUT CHAR8 **VarStoreName
1936 )
1937 {
1938 SVfrVarStorageNode *pNode;
1939
1940 if (VarStoreName == NULL) {
1941 return VFR_RETURN_FATAL_ERROR;
1942 }
1943
1944 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1945 if (pNode->mVarStoreId == VarStoreId) {
1946 *VarStoreName = pNode->mVarStoreName;
1947 return VFR_RETURN_SUCCESS;
1948 }
1949 }
1950
1951 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1952 if (pNode->mVarStoreId == VarStoreId) {
1953 *VarStoreName = pNode->mVarStoreName;
1954 return VFR_RETURN_SUCCESS;
1955 }
1956 }
1957
1958 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1959 if (pNode->mVarStoreId == VarStoreId) {
1960 *VarStoreName = pNode->mVarStoreName;
1961 return VFR_RETURN_SUCCESS;
1962 }
1963 }
1964
1965 *VarStoreName = NULL;
1966 return VFR_RETURN_UNDEFINED;
1967 }
1968
1969 EFI_VFR_RETURN_CODE
1970 CVfrDataStorage::GetEfiVarStoreInfo (
1971 IN OUT EFI_VARSTORE_INFO *Info
1972 )
1973 {
1974 if (Info == NULL) {
1975 return VFR_RETURN_FATAL_ERROR;
1976 }
1977
1978 if (mCurrVarStorageNode == NULL) {
1979 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
1980 }
1981
1982 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
1983 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
1984 switch (Info->mVarTotalSize) {
1985 case 1:
1986 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
1987 break;
1988 case 2:
1989 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
1990 break;
1991 case 4:
1992 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
1993 break;
1994 case 8:
1995 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
1996 break;
1997 default :
1998 return VFR_RETURN_FATAL_ERROR;
1999 }
2000
2001 return VFR_RETURN_SUCCESS;
2002 }
2003
2004 EFI_VFR_RETURN_CODE
2005 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2006 IN EFI_VARSTORE_INFO *Info
2007 )
2008 {
2009 BufferVarStoreFieldInfoNode *pNew;
2010
2011 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
2012 return VFR_RETURN_FATAL_ERROR;
2013 }
2014
2015 if (mBufferFieldInfoListHead == NULL) {
2016 mBufferFieldInfoListHead = pNew;
2017 mBufferFieldInfoListTail= pNew;
2018 } else {
2019 mBufferFieldInfoListTail->mNext = pNew;
2020 mBufferFieldInfoListTail = pNew;
2021 }
2022
2023 return VFR_RETURN_SUCCESS;
2024 }
2025
2026 EFI_VFR_RETURN_CODE
2027 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2028 IN OUT EFI_VARSTORE_INFO *Info
2029 )
2030 {
2031 BufferVarStoreFieldInfoNode *pNode;
2032
2033 pNode = mBufferFieldInfoListHead;
2034 while (pNode != NULL) {
2035 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
2036 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
2037 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
2038 Info->mVarType = pNode->mVarStoreInfo.mVarType;
2039 return VFR_RETURN_SUCCESS;
2040 }
2041 pNode = pNode->mNext;
2042 }
2043 return VFR_RETURN_FATAL_ERROR;
2044 }
2045
2046 EFI_VFR_RETURN_CODE
2047 CVfrDataStorage::GetNameVarStoreInfo (
2048 OUT EFI_VARSTORE_INFO *Info,
2049 IN UINT32 Index
2050 )
2051 {
2052 if (Info == NULL) {
2053 return VFR_RETURN_FATAL_ERROR;
2054 }
2055
2056 if (mCurrVarStorageNode == NULL) {
2057 return VFR_RETURN_GET_NVVARSTORE_ERROR;
2058 }
2059
2060 //
2061 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
2062 //
2063 if (VfrCompatibleMode) {
2064 if (Index == 0) {
2065 return VFR_RETURN_ERROR_ARRARY_NUM;
2066 }
2067 Index --;
2068 }
2069
2070 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
2071
2072 return VFR_RETURN_SUCCESS;
2073 }
2074
2075 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2076 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
2077 IN CHAR8 *RefName,
2078 IN EFI_STRING_ID DefaultStoreNameId,
2079 IN UINT16 DefaultId
2080 )
2081 {
2082 mObjBinAddr = ObjBinAddr;
2083
2084 if (RefName != NULL) {
2085 mRefName = new CHAR8[strlen (RefName) + 1];
2086 strcpy (mRefName, RefName);
2087 } else {
2088 mRefName = NULL;
2089 }
2090
2091 mNext = NULL;
2092 mDefaultId = DefaultId;
2093 mDefaultStoreNameId = DefaultStoreNameId;
2094 }
2095
2096 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2097 VOID
2098 )
2099 {
2100 if (mRefName != NULL) {
2101 delete mRefName;
2102 }
2103 }
2104
2105 CVfrDefaultStore::CVfrDefaultStore (
2106 VOID
2107 )
2108 {
2109 mDefaultStoreList = NULL;
2110 }
2111
2112 CVfrDefaultStore::~CVfrDefaultStore (
2113 VOID
2114 )
2115 {
2116 SVfrDefaultStoreNode *pTmp = NULL;
2117
2118 while (mDefaultStoreList != NULL) {
2119 pTmp = mDefaultStoreList;
2120 mDefaultStoreList = mDefaultStoreList->mNext;
2121 delete pTmp;
2122 }
2123 }
2124
2125 EFI_VFR_RETURN_CODE
2126 CVfrDefaultStore::RegisterDefaultStore (
2127 IN CHAR8 *ObjBinAddr,
2128 IN CHAR8 *RefName,
2129 IN EFI_STRING_ID DefaultStoreNameId,
2130 IN UINT16 DefaultId
2131 )
2132 {
2133 SVfrDefaultStoreNode *pNode = NULL;
2134
2135 if (RefName == NULL) {
2136 return VFR_RETURN_FATAL_ERROR;
2137 }
2138
2139 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2140 if (strcmp (pNode->mRefName, RefName) == 0) {
2141 return VFR_RETURN_REDEFINED;
2142 }
2143 }
2144
2145 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
2146 return VFR_RETURN_OUT_FOR_RESOURCES;
2147 }
2148
2149 pNode->mNext = mDefaultStoreList;
2150 mDefaultStoreList = pNode;
2151
2152 return VFR_RETURN_SUCCESS;
2153 }
2154
2155 /*
2156 * assign new reference name or new default store name id only if
2157 * the original is invalid
2158 */
2159 EFI_VFR_RETURN_CODE
2160 CVfrDefaultStore::ReRegisterDefaultStoreById (
2161 IN UINT16 DefaultId,
2162 IN CHAR8 *RefName,
2163 IN EFI_STRING_ID DefaultStoreNameId
2164 )
2165 {
2166 SVfrDefaultStoreNode *pNode = NULL;
2167
2168 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2169 if (pNode->mDefaultId == DefaultId) {
2170 break;
2171 }
2172 }
2173
2174 if (pNode == NULL) {
2175 return VFR_RETURN_UNDEFINED;
2176 } else {
2177 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
2178 pNode->mDefaultStoreNameId = DefaultStoreNameId;
2179 if (pNode->mObjBinAddr != NULL) {
2180 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
2181 }
2182 } else {
2183 return VFR_RETURN_REDEFINED;
2184 }
2185
2186 if (RefName != NULL) {
2187 delete pNode->mRefName;
2188 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
2189 if (pNode->mRefName != NULL) {
2190 strcpy (pNode->mRefName, RefName);
2191 }
2192 }
2193 }
2194
2195 return VFR_RETURN_SUCCESS;
2196 }
2197
2198 BOOLEAN
2199 CVfrDefaultStore::DefaultIdRegistered (
2200 IN UINT16 DefaultId
2201 )
2202 {
2203 SVfrDefaultStoreNode *pNode = NULL;
2204
2205 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2206 if (pNode->mDefaultId == DefaultId) {
2207 return TRUE;
2208 }
2209 }
2210
2211 return FALSE;
2212 }
2213
2214 EFI_VFR_RETURN_CODE
2215 CVfrDefaultStore::GetDefaultId (
2216 IN CHAR8 *RefName,
2217 OUT UINT16 *DefaultId
2218 )
2219 {
2220 SVfrDefaultStoreNode *pTmp = NULL;
2221
2222 if (DefaultId == NULL) {
2223 return VFR_RETURN_FATAL_ERROR;
2224 }
2225
2226 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2227 if (strcmp (pTmp->mRefName, RefName) == 0) {
2228 *DefaultId = pTmp->mDefaultId;
2229 return VFR_RETURN_SUCCESS;
2230 }
2231 }
2232
2233 return VFR_RETURN_UNDEFINED;
2234 }
2235
2236 EFI_VFR_RETURN_CODE
2237 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2238 IN EFI_VARSTORE_ID DefaultId,
2239 IN EFI_VARSTORE_INFO &Info,
2240 IN CHAR8 *VarStoreName,
2241 IN EFI_GUID *VarStoreGuid,
2242 IN UINT8 Type,
2243 IN EFI_IFR_TYPE_VALUE Value
2244 )
2245 {
2246 SVfrDefaultStoreNode *pNode = NULL;
2247 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2248 INTN Returnvalue = 0;
2249
2250 if (VarStoreName == NULL) {
2251 return VFR_RETURN_FATAL_ERROR;
2252 }
2253
2254 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2255 if (pNode->mDefaultId == DefaultId) {
2256 break;
2257 }
2258 }
2259
2260 if (pNode == NULL) {
2261 return VFR_RETURN_UNDEFINED;
2262 }
2263
2264 gCVfrBufferConfig.Open ();
2265
2266 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2267 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
2268 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2269 goto WriteError;
2270 }
2271 }
2272
2273 gCVfrBufferConfig.Close ();
2274
2275 return VFR_RETURN_SUCCESS;
2276
2277 WriteError:
2278 gCVfrBufferConfig.Close ();
2279 return (EFI_VFR_RETURN_CODE)Returnvalue;
2280 }
2281
2282 SVfrRuleNode::SVfrRuleNode (
2283 IN CHAR8 *RuleName,
2284 IN UINT8 RuleId
2285 )
2286 {
2287 if (RuleName != NULL) {
2288 mRuleName = new CHAR8[strlen (RuleName) + 1];
2289 strcpy (mRuleName, RuleName);
2290 } else {
2291 mRuleName = NULL;
2292 }
2293
2294 mNext = NULL;
2295 mRuleId = RuleId;
2296 }
2297
2298 SVfrRuleNode::~SVfrRuleNode (
2299 VOID
2300 )
2301 {
2302 if (mRuleName != NULL) {
2303 delete mRuleName;
2304 }
2305 }
2306
2307 CVfrRulesDB::CVfrRulesDB ()
2308 {
2309 mRuleList = NULL;
2310 mFreeRuleId = EFI_VARSTORE_ID_START;
2311 }
2312
2313 CVfrRulesDB::~CVfrRulesDB ()
2314 {
2315 SVfrRuleNode *pNode;
2316
2317 while(mRuleList != NULL) {
2318 pNode = mRuleList;
2319 mRuleList = mRuleList->mNext;
2320 delete pNode;
2321 }
2322 }
2323
2324 VOID
2325 CVfrRulesDB::RegisterRule (
2326 IN CHAR8 *RuleName
2327 )
2328 {
2329 SVfrRuleNode *pNew;
2330
2331 if (RuleName == NULL) {
2332 return ;
2333 }
2334
2335 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2336 return ;
2337 }
2338
2339 mFreeRuleId++;
2340
2341 pNew->mNext = mRuleList;
2342 mRuleList = pNew;
2343 }
2344
2345 UINT8
2346 CVfrRulesDB::GetRuleId (
2347 IN CHAR8 *RuleName
2348 )
2349 {
2350 SVfrRuleNode *pNode;
2351
2352 if (RuleName == NULL) {
2353 return EFI_RULE_ID_INVALID;
2354 }
2355
2356 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2357 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2358 return pNode->mRuleId;
2359 }
2360 }
2361
2362 return EFI_RULE_ID_INVALID;
2363 }
2364
2365 CVfrRulesDB gCVfrRulesDB;
2366
2367 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2368 VOID
2369 )
2370 {
2371 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2372 mInfo.mVarName = EFI_STRING_ID_INVALID;
2373 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2374 mVarType = EFI_IFR_TYPE_OTHER;
2375 mVarTotalSize = 0;
2376 }
2377
2378 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2379 IN EFI_VARSTORE_INFO &Info
2380 )
2381 {
2382 mVarStoreId = Info.mVarStoreId;
2383 mInfo.mVarName = Info.mInfo.mVarName;
2384 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2385 mVarType = Info.mVarType;
2386 mVarTotalSize = Info.mVarTotalSize;
2387 }
2388
2389 BOOLEAN
2390 EFI_VARSTORE_INFO::operator == (
2391 IN EFI_VARSTORE_INFO *Info
2392 )
2393 {
2394 if ((mVarStoreId == Info->mVarStoreId) &&
2395 (mInfo.mVarName == Info->mInfo.mVarName) &&
2396 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2397 (mVarType == Info->mVarType) &&
2398 (mVarTotalSize == Info->mVarTotalSize)) {
2399 return TRUE;
2400 }
2401
2402 return FALSE;
2403 }
2404
2405 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2406 IN EFI_VARSTORE_INFO *Info
2407 )
2408 {
2409 mVarStoreInfo.mVarType = Info->mVarType;
2410 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
2411 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
2412 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
2413 mNext = NULL;
2414 }
2415
2416 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2417 {
2418 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
2419 mVarStoreInfo.mVarTotalSize = 0;
2420 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2421 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
2422 mNext = NULL;
2423 }
2424
2425 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2426
2427 EFI_QUESTION_ID
2428 CVfrQuestionDB::GetFreeQuestionId (
2429 VOID
2430 )
2431 {
2432 UINT32 Index, Mask, Offset;
2433
2434 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2435 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2436 break;
2437 }
2438 }
2439
2440 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2441 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2442 mFreeQIdBitMap[Index] |= Mask;
2443 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2444 }
2445 }
2446
2447 return EFI_QUESTION_ID_INVALID;
2448 }
2449
2450 BOOLEAN
2451 CVfrQuestionDB::ChekQuestionIdFree (
2452 IN EFI_QUESTION_ID QId
2453 )
2454 {
2455 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2456 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2457
2458 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2459 }
2460
2461 VOID
2462 CVfrQuestionDB::MarkQuestionIdUsed (
2463 IN EFI_QUESTION_ID QId
2464 )
2465 {
2466 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2467 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2468
2469 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2470 }
2471
2472 VOID
2473 CVfrQuestionDB::MarkQuestionIdUnused (
2474 IN EFI_QUESTION_ID QId
2475 )
2476 {
2477 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2478 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2479
2480 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2481 }
2482
2483 SVfrQuestionNode::SVfrQuestionNode (
2484 IN CHAR8 *Name,
2485 IN CHAR8 *VarIdStr,
2486 IN UINT32 BitMask
2487 )
2488 {
2489 mName = NULL;
2490 mVarIdStr = NULL;
2491 mQuestionId = EFI_QUESTION_ID_INVALID;
2492 mBitMask = BitMask;
2493 mNext = NULL;
2494 mQtype = QUESTION_NORMAL;
2495
2496 if (Name == NULL) {
2497 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2498 strcpy (mName, "$DEFAULT");
2499 } else {
2500 mName = new CHAR8[strlen (Name) + 1];
2501 strcpy (mName, Name);
2502 }
2503
2504 if (VarIdStr != NULL) {
2505 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2506 strcpy (mVarIdStr, VarIdStr);
2507 } else {
2508 mVarIdStr = new CHAR8[strlen ("$") + 1];
2509 strcpy (mVarIdStr, "$");
2510 }
2511 }
2512
2513 SVfrQuestionNode::~SVfrQuestionNode (
2514 VOID
2515 )
2516 {
2517 if (mName != NULL) {
2518 delete mName;
2519 }
2520
2521 if (mVarIdStr != NULL) {
2522 delete mVarIdStr;
2523 }
2524 }
2525
2526 CVfrQuestionDB::CVfrQuestionDB ()
2527 {
2528 UINT32 Index;
2529
2530 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2531 mFreeQIdBitMap[Index] = 0;
2532 }
2533
2534 // Question ID 0 is reserved.
2535 mFreeQIdBitMap[0] = 0x80000000;
2536 mQuestionList = NULL;
2537 }
2538
2539 CVfrQuestionDB::~CVfrQuestionDB ()
2540 {
2541 SVfrQuestionNode *pNode;
2542
2543 while (mQuestionList != NULL) {
2544 pNode = mQuestionList;
2545 mQuestionList = mQuestionList->mNext;
2546 delete pNode;
2547 }
2548 }
2549
2550 //
2551 // Reset to init state
2552 //
2553 VOID
2554 CVfrQuestionDB::ResetInit(
2555 IN VOID
2556 )
2557 {
2558 UINT32 Index;
2559 SVfrQuestionNode *pNode;
2560
2561 while (mQuestionList != NULL) {
2562 pNode = mQuestionList;
2563 mQuestionList = mQuestionList->mNext;
2564 delete pNode;
2565 }
2566
2567 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2568 mFreeQIdBitMap[Index] = 0;
2569 }
2570
2571 // Question ID 0 is reserved.
2572 mFreeQIdBitMap[0] = 0x80000000;
2573 mQuestionList = NULL;
2574 }
2575
2576 VOID
2577 CVfrQuestionDB::PrintAllQuestion (
2578 VOID
2579 )
2580 {
2581 SVfrQuestionNode *pNode = NULL;
2582
2583 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2584 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2585 }
2586 }
2587
2588 EFI_VFR_RETURN_CODE
2589 CVfrQuestionDB::RegisterQuestion (
2590 IN CHAR8 *Name,
2591 IN CHAR8 *VarIdStr,
2592 IN OUT EFI_QUESTION_ID &QuestionId
2593 )
2594 {
2595 SVfrQuestionNode *pNode = NULL;
2596
2597 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2598 return VFR_RETURN_REDEFINED;
2599 }
2600
2601 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2602 return VFR_RETURN_OUT_FOR_RESOURCES;
2603 }
2604
2605 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2606 QuestionId = GetFreeQuestionId ();
2607 } else {
2608 //
2609 // For Framework Vfr, don't check question ID conflict.
2610 //
2611 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
2612 delete pNode;
2613 return VFR_RETURN_QUESTIONID_REDEFINED;
2614 }
2615 MarkQuestionIdUsed (QuestionId);
2616 }
2617 pNode->mQuestionId = QuestionId;
2618
2619 pNode->mNext = mQuestionList;
2620 mQuestionList = pNode;
2621
2622 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2623
2624 return VFR_RETURN_SUCCESS;
2625 }
2626
2627 VOID
2628 CVfrQuestionDB::RegisterOldDateQuestion (
2629 IN CHAR8 *YearVarId,
2630 IN CHAR8 *MonthVarId,
2631 IN CHAR8 *DayVarId,
2632 IN OUT EFI_QUESTION_ID &QuestionId
2633 )
2634 {
2635 SVfrQuestionNode *pNode[3] = {NULL, };
2636 UINT32 Index;
2637
2638 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2639 return;
2640 }
2641
2642 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2643 goto Err;
2644 }
2645 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2646 goto Err;
2647 }
2648 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2649 goto Err;
2650 }
2651
2652 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2653 QuestionId = GetFreeQuestionId ();
2654 } else {
2655 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2656 goto Err;
2657 }
2658 MarkQuestionIdUsed (QuestionId);
2659 }
2660
2661 pNode[0]->mQuestionId = QuestionId;
2662 pNode[1]->mQuestionId = QuestionId;
2663 pNode[2]->mQuestionId = QuestionId;
2664 pNode[0]->mQtype = QUESTION_DATE;
2665 pNode[1]->mQtype = QUESTION_DATE;
2666 pNode[2]->mQtype = QUESTION_DATE;
2667 pNode[0]->mNext = pNode[1];
2668 pNode[1]->mNext = pNode[2];
2669 pNode[2]->mNext = mQuestionList;
2670 mQuestionList = pNode[0];
2671
2672 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2673 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2674 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2675
2676 return;
2677
2678 Err:
2679 for (Index = 0; Index < 3; Index++) {
2680 if (pNode[Index] != NULL) {
2681 delete pNode[Index];
2682 }
2683 }
2684 QuestionId = EFI_QUESTION_ID_INVALID;
2685 }
2686
2687 VOID
2688 CVfrQuestionDB::RegisterNewDateQuestion (
2689 IN CHAR8 *Name,
2690 IN CHAR8 *BaseVarId,
2691 IN OUT EFI_QUESTION_ID &QuestionId
2692 )
2693 {
2694 SVfrQuestionNode *pNode[3] = {NULL, };
2695 UINT32 Len;
2696 CHAR8 *VarIdStr[3] = {NULL, };
2697 CHAR8 Index;
2698
2699 if (BaseVarId == NULL && Name == NULL) {
2700 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2701 QuestionId = GetFreeQuestionId ();
2702 } else {
2703 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2704 goto Err;
2705 }
2706 MarkQuestionIdUsed (QuestionId);
2707 }
2708 return;
2709 }
2710
2711 if (BaseVarId != NULL) {
2712 Len = strlen (BaseVarId);
2713
2714 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2715 if (VarIdStr[0] != NULL) {
2716 strcpy (VarIdStr[0], BaseVarId);
2717 strcat (VarIdStr[0], ".Year");
2718 }
2719 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2720 if (VarIdStr[1] != NULL) {
2721 strcpy (VarIdStr[1], BaseVarId);
2722 strcat (VarIdStr[1], ".Month");
2723 }
2724 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2725 if (VarIdStr[2] != NULL) {
2726 strcpy (VarIdStr[2], BaseVarId);
2727 strcat (VarIdStr[2], ".Day");
2728 }
2729 } else {
2730 Len = strlen (Name);
2731
2732 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2733 if (VarIdStr[0] != NULL) {
2734 strcpy (VarIdStr[0], Name);
2735 strcat (VarIdStr[0], ".Year");
2736 }
2737 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2738 if (VarIdStr[1] != NULL) {
2739 strcpy (VarIdStr[1], Name);
2740 strcat (VarIdStr[1], ".Month");
2741 }
2742 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2743 if (VarIdStr[2] != NULL) {
2744 strcpy (VarIdStr[2], Name);
2745 strcat (VarIdStr[2], ".Day");
2746 }
2747 }
2748
2749 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2750 goto Err;
2751 }
2752 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2753 goto Err;
2754 }
2755 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2756 goto Err;
2757 }
2758
2759 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2760 QuestionId = GetFreeQuestionId ();
2761 } else {
2762 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2763 goto Err;
2764 }
2765 MarkQuestionIdUsed (QuestionId);
2766 }
2767
2768 pNode[0]->mQuestionId = QuestionId;
2769 pNode[1]->mQuestionId = QuestionId;
2770 pNode[2]->mQuestionId = QuestionId;
2771 pNode[0]->mQtype = QUESTION_DATE;
2772 pNode[1]->mQtype = QUESTION_DATE;
2773 pNode[2]->mQtype = QUESTION_DATE;
2774 pNode[0]->mNext = pNode[1];
2775 pNode[1]->mNext = pNode[2];
2776 pNode[2]->mNext = mQuestionList;
2777 mQuestionList = pNode[0];
2778
2779 for (Index = 0; Index < 3; Index++) {
2780 if (VarIdStr[Index] != NULL) {
2781 delete VarIdStr[Index];
2782 }
2783 }
2784
2785 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2786 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2787 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2788
2789 return;
2790
2791 Err:
2792 for (Index = 0; Index < 3; Index++) {
2793 if (pNode[Index] != NULL) {
2794 delete pNode[Index];
2795 }
2796
2797 if (VarIdStr[Index] != NULL) {
2798 delete VarIdStr[Index];
2799 }
2800 }
2801 }
2802
2803 VOID
2804 CVfrQuestionDB::RegisterOldTimeQuestion (
2805 IN CHAR8 *HourVarId,
2806 IN CHAR8 *MinuteVarId,
2807 IN CHAR8 *SecondVarId,
2808 IN OUT EFI_QUESTION_ID &QuestionId
2809 )
2810 {
2811 SVfrQuestionNode *pNode[3] = {NULL, };
2812 UINT32 Index;
2813
2814 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
2815 return;
2816 }
2817
2818 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
2819 goto Err;
2820 }
2821 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
2822 goto Err;
2823 }
2824 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
2825 goto Err;
2826 }
2827
2828 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2829 QuestionId = GetFreeQuestionId ();
2830 } else {
2831 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2832 goto Err;
2833 }
2834 MarkQuestionIdUsed (QuestionId);
2835 }
2836
2837 pNode[0]->mQuestionId = QuestionId;
2838 pNode[1]->mQuestionId = QuestionId;
2839 pNode[2]->mQuestionId = QuestionId;
2840 pNode[0]->mQtype = QUESTION_TIME;
2841 pNode[1]->mQtype = QUESTION_TIME;
2842 pNode[2]->mQtype = QUESTION_TIME;
2843 pNode[0]->mNext = pNode[1];
2844 pNode[1]->mNext = pNode[2];
2845 pNode[2]->mNext = mQuestionList;
2846 mQuestionList = pNode[0];
2847
2848 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2849 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2850 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2851
2852 return;
2853
2854 Err:
2855 for (Index = 0; Index < 3; Index++) {
2856 if (pNode[Index] != NULL) {
2857 delete pNode[Index];
2858 }
2859 }
2860 QuestionId = EFI_QUESTION_ID_INVALID;
2861 }
2862
2863 VOID
2864 CVfrQuestionDB::RegisterNewTimeQuestion (
2865 IN CHAR8 *Name,
2866 IN CHAR8 *BaseVarId,
2867 IN OUT EFI_QUESTION_ID &QuestionId
2868 )
2869 {
2870 SVfrQuestionNode *pNode[3] = {NULL, };
2871 UINT32 Len;
2872 CHAR8 *VarIdStr[3] = {NULL, };
2873 CHAR8 Index;
2874
2875 if (BaseVarId == NULL && Name == NULL) {
2876 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2877 QuestionId = GetFreeQuestionId ();
2878 } else {
2879 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2880 goto Err;
2881 }
2882 MarkQuestionIdUsed (QuestionId);
2883 }
2884 return;
2885 }
2886
2887 if (BaseVarId != NULL) {
2888 Len = strlen (BaseVarId);
2889
2890 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2891 if (VarIdStr[0] != NULL) {
2892 strcpy (VarIdStr[0], BaseVarId);
2893 strcat (VarIdStr[0], ".Hour");
2894 }
2895 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2896 if (VarIdStr[1] != NULL) {
2897 strcpy (VarIdStr[1], BaseVarId);
2898 strcat (VarIdStr[1], ".Minute");
2899 }
2900 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2901 if (VarIdStr[2] != NULL) {
2902 strcpy (VarIdStr[2], BaseVarId);
2903 strcat (VarIdStr[2], ".Second");
2904 }
2905 } else {
2906 Len = strlen (Name);
2907
2908 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
2909 if (VarIdStr[0] != NULL) {
2910 strcpy (VarIdStr[0], Name);
2911 strcat (VarIdStr[0], ".Hour");
2912 }
2913 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
2914 if (VarIdStr[1] != NULL) {
2915 strcpy (VarIdStr[1], Name);
2916 strcat (VarIdStr[1], ".Minute");
2917 }
2918 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
2919 if (VarIdStr[2] != NULL) {
2920 strcpy (VarIdStr[2], Name);
2921 strcat (VarIdStr[2], ".Second");
2922 }
2923 }
2924
2925 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
2926 goto Err;
2927 }
2928 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
2929 goto Err;
2930 }
2931 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
2932 goto Err;
2933 }
2934
2935 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2936 QuestionId = GetFreeQuestionId ();
2937 } else {
2938 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2939 goto Err;
2940 }
2941 MarkQuestionIdUsed (QuestionId);
2942 }
2943
2944 pNode[0]->mQuestionId = QuestionId;
2945 pNode[1]->mQuestionId = QuestionId;
2946 pNode[2]->mQuestionId = QuestionId;
2947 pNode[0]->mQtype = QUESTION_TIME;
2948 pNode[1]->mQtype = QUESTION_TIME;
2949 pNode[2]->mQtype = QUESTION_TIME;
2950 pNode[0]->mNext = pNode[1];
2951 pNode[1]->mNext = pNode[2];
2952 pNode[2]->mNext = mQuestionList;
2953 mQuestionList = pNode[0];
2954
2955 for (Index = 0; Index < 3; Index++) {
2956 if (VarIdStr[Index] != NULL) {
2957 delete VarIdStr[Index];
2958 }
2959 }
2960
2961 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2962 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2963 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2964
2965 return;
2966
2967 Err:
2968 for (Index = 0; Index < 3; Index++) {
2969 if (pNode[Index] != NULL) {
2970 delete pNode[Index];
2971 }
2972
2973 if (VarIdStr[Index] != NULL) {
2974 delete VarIdStr[Index];
2975 }
2976 }
2977 }
2978
2979 VOID
2980 CVfrQuestionDB::RegisterRefQuestion (
2981 IN CHAR8 *Name,
2982 IN CHAR8 *BaseVarId,
2983 IN OUT EFI_QUESTION_ID &QuestionId
2984 )
2985 {
2986 SVfrQuestionNode *pNode[4] = {NULL, };
2987 UINT32 Len;
2988 CHAR8 *VarIdStr[4] = {NULL, };
2989 CHAR8 Index;
2990
2991 if (BaseVarId == NULL && Name == NULL) {
2992 return;
2993 }
2994
2995 if (BaseVarId != NULL) {
2996 Len = strlen (BaseVarId);
2997
2998 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
2999 if (VarIdStr[0] != NULL) {
3000 strcpy (VarIdStr[0], BaseVarId);
3001 strcat (VarIdStr[0], ".QuestionId");
3002 }
3003 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3004 if (VarIdStr[1] != NULL) {
3005 strcpy (VarIdStr[1], BaseVarId);
3006 strcat (VarIdStr[1], ".FormId");
3007 }
3008 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3009 if (VarIdStr[2] != NULL) {
3010 strcpy (VarIdStr[2], BaseVarId);
3011 strcat (VarIdStr[2], ".FormSetGuid");
3012 }
3013 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3014 if (VarIdStr[3] != NULL) {
3015 strcpy (VarIdStr[3], BaseVarId);
3016 strcat (VarIdStr[3], ".DevicePath");
3017 }
3018 } else {
3019 Len = strlen (Name);
3020
3021 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3022 if (VarIdStr[0] != NULL) {
3023 strcpy (VarIdStr[0], Name);
3024 strcat (VarIdStr[0], ".QuestionId");
3025 }
3026 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3027 if (VarIdStr[1] != NULL) {
3028 strcpy (VarIdStr[1], Name);
3029 strcat (VarIdStr[1], ".FormId");
3030 }
3031 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3032 if (VarIdStr[2] != NULL) {
3033 strcpy (VarIdStr[2], Name);
3034 strcat (VarIdStr[2], ".FormSetGuid");
3035 }
3036 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3037 if (VarIdStr[3] != NULL) {
3038 strcpy (VarIdStr[3], Name);
3039 strcat (VarIdStr[3], ".DevicePath");
3040 }
3041 }
3042
3043 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
3044 goto Err;
3045 }
3046 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
3047 goto Err;
3048 }
3049 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
3050 goto Err;
3051 }
3052 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
3053 goto Err;
3054 }
3055
3056 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3057 QuestionId = GetFreeQuestionId ();
3058 } else {
3059 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3060 goto Err;
3061 }
3062 MarkQuestionIdUsed (QuestionId);
3063 }
3064
3065 pNode[0]->mQuestionId = QuestionId;
3066 pNode[1]->mQuestionId = QuestionId;
3067 pNode[2]->mQuestionId = QuestionId;
3068 pNode[3]->mQuestionId = QuestionId;
3069 pNode[0]->mQtype = QUESTION_REF;
3070 pNode[1]->mQtype = QUESTION_REF;
3071 pNode[2]->mQtype = QUESTION_REF;
3072 pNode[3]->mQtype = QUESTION_REF;
3073 pNode[0]->mNext = pNode[1];
3074 pNode[1]->mNext = pNode[2];
3075 pNode[2]->mNext = pNode[3];
3076 pNode[3]->mNext = mQuestionList;
3077 mQuestionList = pNode[0];
3078
3079 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3080 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3081 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3082 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3083
3084 return;
3085
3086 Err:
3087 for (Index = 0; Index < 4; Index++) {
3088 if (pNode[Index] != NULL) {
3089 delete pNode[Index];
3090 }
3091
3092 if (VarIdStr[Index] != NULL) {
3093 delete VarIdStr[Index];
3094 }
3095 }
3096 }
3097
3098 EFI_VFR_RETURN_CODE
3099 CVfrQuestionDB::UpdateQuestionId (
3100 IN EFI_QUESTION_ID QId,
3101 IN EFI_QUESTION_ID NewQId
3102 )
3103 {
3104 SVfrQuestionNode *pNode = NULL;
3105
3106 if (QId == NewQId) {
3107 // don't update
3108 return VFR_RETURN_SUCCESS;
3109 }
3110
3111 //
3112 // For Framework Vfr, don't check question ID conflict.
3113 //
3114 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
3115 return VFR_RETURN_REDEFINED;
3116 }
3117
3118 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3119 if (pNode->mQuestionId == QId) {
3120 break;
3121 }
3122 }
3123
3124 if (pNode == NULL) {
3125 return VFR_RETURN_UNDEFINED;
3126 }
3127
3128 MarkQuestionIdUnused (QId);
3129 pNode->mQuestionId = NewQId;
3130 MarkQuestionIdUsed (NewQId);
3131
3132 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
3133
3134 return VFR_RETURN_SUCCESS;
3135 }
3136
3137 VOID
3138 CVfrQuestionDB::GetQuestionId (
3139 IN CHAR8 *Name,
3140 IN CHAR8 *VarIdStr,
3141 OUT EFI_QUESTION_ID &QuestionId,
3142 OUT UINT32 &BitMask,
3143 OUT EFI_QUESION_TYPE *QType
3144 )
3145 {
3146 SVfrQuestionNode *pNode;
3147
3148 QuestionId = EFI_QUESTION_ID_INVALID;
3149 BitMask = 0x00000000;
3150 if (QType != NULL) {
3151 *QType = QUESTION_NORMAL;
3152 }
3153
3154 if ((Name == NULL) && (VarIdStr == NULL)) {
3155 return ;
3156 }
3157
3158 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3159 if (Name != NULL) {
3160 if (strcmp (pNode->mName, Name) != 0) {
3161 continue;
3162 }
3163 }
3164
3165 if (VarIdStr != NULL) {
3166 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
3167 continue;
3168 }
3169 }
3170
3171 QuestionId = pNode->mQuestionId;
3172 BitMask = pNode->mBitMask;
3173 if (QType != NULL) {
3174 *QType = pNode->mQtype;
3175 }
3176 break;
3177 }
3178
3179 return ;
3180 }
3181
3182 EFI_VFR_RETURN_CODE
3183 CVfrQuestionDB::FindQuestion (
3184 IN EFI_QUESTION_ID QuestionId
3185 )
3186 {
3187 SVfrQuestionNode *pNode;
3188
3189 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3190 return VFR_RETURN_INVALID_PARAMETER;
3191 }
3192
3193 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3194 if (pNode->mQuestionId == QuestionId) {
3195 return VFR_RETURN_SUCCESS;
3196 }
3197 }
3198
3199 return VFR_RETURN_UNDEFINED;
3200 }
3201
3202 EFI_VFR_RETURN_CODE
3203 CVfrQuestionDB::FindQuestion (
3204 IN CHAR8 *Name
3205 )
3206 {
3207 SVfrQuestionNode *pNode;
3208
3209 if (Name == NULL) {
3210 return VFR_RETURN_FATAL_ERROR;
3211 }
3212
3213 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3214 if (strcmp (pNode->mName, Name) == 0) {
3215 return VFR_RETURN_SUCCESS;
3216 }
3217 }
3218
3219 return VFR_RETURN_UNDEFINED;
3220 }
3221
3222 CVfrStringDB::CVfrStringDB ()
3223 {
3224 mStringFileName = NULL;
3225 }
3226
3227 CVfrStringDB::~CVfrStringDB ()
3228 {
3229 if (mStringFileName != NULL) {
3230 delete mStringFileName;
3231 }
3232 mStringFileName = NULL;
3233 }
3234
3235
3236 VOID
3237 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
3238 {
3239 UINT32 FileLen = 0;
3240
3241 if (StringFileName == NULL) {
3242 return;
3243 }
3244
3245 FileLen = strlen (StringFileName) + 1;
3246 mStringFileName = new CHAR8[FileLen];
3247 if (mStringFileName == NULL) {
3248 return;
3249 }
3250
3251 strcpy (mStringFileName, StringFileName);
3252 mStringFileName[FileLen - 1] = '\0';
3253 }
3254
3255
3256 /**
3257 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3258 from a set of supported languages.
3259
3260 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3261 contains a set of language codes.
3262 @param[in] Language A variable that contains pointers to Null-terminated
3263 ASCII strings that contain one language codes.
3264
3265 @retval FALSE The best matching language could not be found in SupportedLanguages.
3266 @retval TRUE The best matching language could be found in SupportedLanguages.
3267
3268 **/
3269 BOOLEAN
3270 CVfrStringDB::GetBestLanguage (
3271 IN CONST CHAR8 *SupportedLanguages,
3272 IN CHAR8 *Language
3273 )
3274 {
3275 UINTN CompareLength;
3276 UINTN LanguageLength;
3277 CONST CHAR8 *Supported;
3278
3279 if (SupportedLanguages == NULL || Language == NULL){
3280 return FALSE;
3281 }
3282
3283 //
3284 // Determine the length of the first RFC 4646 language code in Language
3285 //
3286 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
3287
3288 //
3289 // Trim back the length of Language used until it is empty
3290 //
3291 while (LanguageLength > 0) {
3292 //
3293 // Loop through all language codes in SupportedLanguages
3294 //
3295 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
3296 //
3297 // Skip ';' characters in Supported
3298 //
3299 for (; *Supported != '\0' && *Supported == ';'; Supported++);
3300 //
3301 // Determine the length of the next language code in Supported
3302 //
3303 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
3304 //
3305 // If Language is longer than the Supported, then skip to the next language
3306 //
3307 if (LanguageLength > CompareLength) {
3308 continue;
3309 }
3310
3311 //
3312 // See if the first LanguageLength characters in Supported match Language
3313 //
3314 if (strncmp (Supported, Language, LanguageLength) == 0) {
3315 return TRUE;
3316 }
3317 }
3318
3319 //
3320 // Trim Language from the right to the next '-' character
3321 //
3322 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
3323 }
3324
3325 //
3326 // No matches were found
3327 //
3328 return FALSE;
3329 }
3330
3331
3332 CHAR8 *
3333 CVfrStringDB::GetVarStoreNameFormStringId (
3334 IN EFI_STRING_ID StringId
3335 )
3336 {
3337 FILE *pInFile = NULL;
3338 UINT32 NameOffset;
3339 UINT32 Length;
3340 UINT8 *StringPtr;
3341 CHAR8 *StringName;
3342 CHAR16 *UnicodeString;
3343 CHAR8 *VarStoreName = NULL;
3344 CHAR8 *DestTmp;
3345 UINT8 *Current;
3346 EFI_STATUS Status;
3347 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
3348 UINT8 BlockType;
3349 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
3350
3351 if (mStringFileName == '\0' ) {
3352 return NULL;
3353 }
3354
3355 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
3356 return NULL;
3357 }
3358
3359 //
3360 // Get file length.
3361 //
3362 fseek (pInFile, 0, SEEK_END);
3363 Length = ftell (pInFile);
3364 fseek (pInFile, 0, SEEK_SET);
3365
3366 //
3367 // Get file data.
3368 //
3369 StringPtr = new UINT8[Length];
3370 if (StringPtr == NULL) {
3371 fclose (pInFile);
3372 return NULL;
3373 }
3374 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
3375 fclose (pInFile);
3376
3377 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3378 //
3379 // Check the String package.
3380 //
3381 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
3382 delete StringPtr;
3383 return NULL;
3384 }
3385
3386 //
3387 // Search the language, get best language base on RFC 4647 matching algorithm.
3388 //
3389 Current = StringPtr;
3390 while (!GetBestLanguage ("en", PkgHeader->Language)) {
3391 Current += PkgHeader->Header.Length;
3392 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
3393 //
3394 // If can't find string package base on language, just return the first string package.
3395 //
3396 if (Current - StringPtr >= Length) {
3397 Current = StringPtr;
3398 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3399 break;
3400 }
3401 }
3402
3403 Current += PkgHeader->HdrSize;
3404 //
3405 // Find the string block according the stringId.
3406 //
3407 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
3408 if (Status != EFI_SUCCESS) {
3409 delete StringPtr;
3410 return NULL;
3411 }
3412
3413 //
3414 // Get varstore name according the string type.
3415 //
3416 switch (BlockType) {
3417 case EFI_HII_SIBT_STRING_SCSU:
3418 case EFI_HII_SIBT_STRING_SCSU_FONT:
3419 case EFI_HII_SIBT_STRINGS_SCSU:
3420 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3421 StringName = (CHAR8*)(Current + NameOffset);
3422 VarStoreName = new CHAR8[strlen(StringName) + 1];
3423 strcpy (VarStoreName, StringName);
3424 break;
3425 case EFI_HII_SIBT_STRING_UCS2:
3426 case EFI_HII_SIBT_STRING_UCS2_FONT:
3427 case EFI_HII_SIBT_STRINGS_UCS2:
3428 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3429 UnicodeString = (CHAR16*)(Current + NameOffset);
3430 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
3431 DestTmp = new CHAR8[Length / 2 + 1];
3432 VarStoreName = DestTmp;
3433 while (*UnicodeString != '\0') {
3434 *(DestTmp++) = (CHAR8) *(UnicodeString++);
3435 }
3436 *DestTmp = '\0';
3437 break;
3438 default:
3439 break;
3440 }
3441
3442 delete StringPtr;
3443
3444 return VarStoreName;
3445 }
3446
3447 EFI_STATUS
3448 CVfrStringDB::FindStringBlock (
3449 IN UINT8 *StringData,
3450 IN EFI_STRING_ID StringId,
3451 OUT UINT32 *StringTextOffset,
3452 OUT UINT8 *BlockType
3453 )
3454 {
3455 UINT8 *BlockHdr;
3456 EFI_STRING_ID CurrentStringId;
3457 UINT32 BlockSize;
3458 UINT32 Index;
3459 UINT8 *StringTextPtr;
3460 UINT32 Offset;
3461 UINT16 StringCount;
3462 UINT16 SkipCount;
3463 UINT8 Length8;
3464 EFI_HII_SIBT_EXT2_BLOCK Ext2;
3465 UINT32 Length32;
3466 UINT32 StringSize;
3467
3468 CurrentStringId = 1;
3469
3470 //
3471 // Parse the string blocks to get the string text and font.
3472 //
3473 BlockHdr = StringData;
3474 BlockSize = 0;
3475 Offset = 0;
3476 while (*BlockHdr != EFI_HII_SIBT_END) {
3477 switch (*BlockHdr) {
3478 case EFI_HII_SIBT_STRING_SCSU:
3479 Offset = sizeof (EFI_HII_STRING_BLOCK);
3480 StringTextPtr = BlockHdr + Offset;
3481 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3482 CurrentStringId++;
3483 break;
3484
3485 case EFI_HII_SIBT_STRING_SCSU_FONT:
3486 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
3487 StringTextPtr = BlockHdr + Offset;
3488 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3489 CurrentStringId++;
3490 break;
3491
3492 case EFI_HII_SIBT_STRINGS_SCSU:
3493 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3494 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
3495 BlockSize += StringTextPtr - BlockHdr;
3496
3497 for (Index = 0; Index < StringCount; Index++) {
3498 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3499 if (CurrentStringId == StringId) {
3500 *BlockType = *BlockHdr;
3501 *StringTextOffset = StringTextPtr - StringData;
3502 return EFI_SUCCESS;
3503 }
3504 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3505 CurrentStringId++;
3506 }
3507 break;
3508
3509 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3510 memcpy (
3511 &StringCount,
3512 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3513 sizeof (UINT16)
3514 );
3515 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
3516 BlockSize += StringTextPtr - BlockHdr;
3517
3518 for (Index = 0; Index < StringCount; Index++) {
3519 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3520 if (CurrentStringId == StringId) {
3521 *BlockType = *BlockHdr;
3522 *StringTextOffset = StringTextPtr - StringData;
3523 return EFI_SUCCESS;
3524 }
3525 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3526 CurrentStringId++;
3527 }
3528 break;
3529
3530 case EFI_HII_SIBT_STRING_UCS2:
3531 Offset = sizeof (EFI_HII_STRING_BLOCK);
3532 StringTextPtr = BlockHdr + Offset;
3533 //
3534 // Use StringSize to store the size of the specified string, including the NULL
3535 // terminator.
3536 //
3537 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3538 BlockSize += Offset + StringSize;
3539 CurrentStringId++;
3540 break;
3541
3542 case EFI_HII_SIBT_STRING_UCS2_FONT:
3543 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3544 StringTextPtr = BlockHdr + Offset;
3545 //
3546 // Use StrSize to store the size of the specified string, including the NULL
3547 // terminator.
3548 //
3549 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3550 BlockSize += Offset + StringSize;
3551 CurrentStringId++;
3552 break;
3553
3554 case EFI_HII_SIBT_STRINGS_UCS2:
3555 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
3556 StringTextPtr = BlockHdr + Offset;
3557 BlockSize += Offset;
3558 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3559 for (Index = 0; Index < StringCount; Index++) {
3560 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3561 BlockSize += StringSize;
3562 if (CurrentStringId == StringId) {
3563 *BlockType = *BlockHdr;
3564 *StringTextOffset = StringTextPtr - StringData;
3565 return EFI_SUCCESS;
3566 }
3567 StringTextPtr = StringTextPtr + StringSize;
3568 CurrentStringId++;
3569 }
3570 break;
3571
3572 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3573 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3574 StringTextPtr = BlockHdr + Offset;
3575 BlockSize += Offset;
3576 memcpy (
3577 &StringCount,
3578 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3579 sizeof (UINT16)
3580 );
3581 for (Index = 0; Index < StringCount; Index++) {
3582 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3583 BlockSize += StringSize;
3584 if (CurrentStringId == StringId) {
3585 *BlockType = *BlockHdr;
3586 *StringTextOffset = StringTextPtr - StringData;
3587 return EFI_SUCCESS;
3588 }
3589 StringTextPtr = StringTextPtr + StringSize;
3590 CurrentStringId++;
3591 }
3592 break;
3593
3594 case EFI_HII_SIBT_DUPLICATE:
3595 if (CurrentStringId == StringId) {
3596 //
3597 // Incoming StringId is an id of a duplicate string block.
3598 // Update the StringId to be the previous string block.
3599 // Go back to the header of string block to search.
3600 //
3601 memcpy (
3602 &StringId,
3603 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
3604 sizeof (EFI_STRING_ID)
3605 );
3606 CurrentStringId = 1;
3607 BlockSize = 0;
3608 } else {
3609 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
3610 CurrentStringId++;
3611 }
3612 break;
3613
3614 case EFI_HII_SIBT_SKIP1:
3615 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
3616 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3617 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
3618 break;
3619
3620 case EFI_HII_SIBT_SKIP2:
3621 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3622 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3623 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
3624 break;
3625
3626 case EFI_HII_SIBT_EXT1:
3627 memcpy (
3628 &Length8,
3629 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3630 sizeof (UINT8)
3631 );
3632 BlockSize += Length8;
3633 break;
3634
3635 case EFI_HII_SIBT_EXT2:
3636 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
3637 BlockSize += Ext2.Length;
3638 break;
3639
3640 case EFI_HII_SIBT_EXT4:
3641 memcpy (
3642 &Length32,
3643 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3644 sizeof (UINT32)
3645 );
3646
3647 BlockSize += Length32;
3648 break;
3649
3650 default:
3651 break;
3652 }
3653
3654 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
3655 *StringTextOffset = BlockHdr - StringData + Offset;
3656 *BlockType = *BlockHdr;
3657
3658 if (StringId == CurrentStringId - 1) {
3659 //
3660 // if only one skip item, return EFI_NOT_FOUND.
3661 //
3662 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
3663 return EFI_NOT_FOUND;
3664 } else {
3665 return EFI_SUCCESS;
3666 }
3667 }
3668
3669 if (StringId < CurrentStringId - 1) {
3670 return EFI_NOT_FOUND;
3671 }
3672 }
3673 BlockHdr = StringData + BlockSize;
3674 }
3675
3676 return EFI_NOT_FOUND;
3677 }
3678
3679 UINT32
3680 CVfrStringDB::GetUnicodeStringTextSize (
3681 IN UINT8 *StringSrc
3682 )
3683 {
3684 UINT32 StringSize;
3685 CHAR16 *StringPtr;
3686
3687 StringSize = sizeof (CHAR16);
3688 StringPtr = (UINT16*)StringSrc;
3689 while (*StringPtr++ != L'\0') {
3690 StringSize += sizeof (CHAR16);
3691 }
3692
3693 return StringSize;
3694 }
3695
3696 BOOLEAN VfrCompatibleMode = FALSE;
3697
3698 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
3699 CVfrDefaultStore gCVfrDefaultStore;
3700 CVfrDataStorage gCVfrDataStorage;
3701
3702