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