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