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