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