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