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