]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools: Fix various typos
[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 }
1139 pNewField->mFieldType = pFieldType;
1140 pNewField->mIsBitField = TRUE;
1141 pNewField->mBitWidth = Width;
1142 pNewField->mArrayNum = 0;
1143 pNewField->mBitOffset = 0;
1144 pNewField->mOffset = 0;
1145
1146 if (mNewDataType->mMembers == NULL) {
1147 mNewDataType->mMembers = pNewField;
1148 pNewField->mNext = NULL;
1149 } else {
1150 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
1151 ;
1152 pTmp->mNext = pNewField;
1153 pNewField->mNext = NULL;
1154 }
1155
1156 if (FieldInUnion) {
1157 pNewField->mOffset = 0;
1158 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
1159 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
1160 }
1161 } else {
1162 //
1163 // Check whether the bit fields can be contained within one FieldType.
1164 //
1165 if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&
1166 (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {
1167 pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;
1168 pNewField->mOffset = pTmp->mOffset;
1169 //
1170 // If BitWidth=0,used to force alignment at the next word boundary.
1171 // So make this bit field occupy the remaing bit width of current field type.
1172 //
1173 if (pNewField->mBitWidth == 0) {
1174 pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);
1175 }
1176 } else {
1177 //
1178 // The bit filed start a new memory
1179 //
1180 pNewField->mBitOffset = mNewDataType->mTotalSize * 8;
1181 UpdateTotalSize = TRUE;
1182 }
1183 }
1184
1185 if (UpdateTotalSize){
1186 if ((mNewDataType->mTotalSize % Align) == 0) {
1187 pNewField->mOffset = mNewDataType->mTotalSize;
1188 } else {
1189 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
1190 }
1191 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);
1192 }
1193
1194 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
1195 mNewDataType->mHasBitField = TRUE;
1196 return VFR_RETURN_SUCCESS;
1197 }
1198
1199 EFI_VFR_RETURN_CODE
1200 CVfrVarDataTypeDB::DataTypeAddField (
1201 IN CHAR8 *FieldName,
1202 IN CHAR8 *TypeName,
1203 IN UINT32 ArrayNum,
1204 IN BOOLEAN FieldInUnion
1205 )
1206 {
1207 SVfrDataField *pNewField = NULL;
1208 SVfrDataType *pFieldType = NULL;
1209 SVfrDataField *pTmp;
1210 UINT32 Align;
1211 UINT32 MaxDataTypeSize;
1212
1213 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
1214 MaxDataTypeSize = mNewDataType->mTotalSize;
1215
1216 if (strlen (FieldName) >= MAX_NAME_LEN) {
1217 return VFR_RETURN_INVALID_PARAMETER;
1218 }
1219
1220 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
1221 if (strcmp (pTmp->mFieldName, FieldName) == 0) {
1222 return VFR_RETURN_REDEFINED;
1223 }
1224 }
1225
1226 Align = MIN (mPackAlign, pFieldType->mAlign);
1227
1228 if ((pNewField = new SVfrDataField) == NULL) {
1229 return VFR_RETURN_OUT_FOR_RESOURCES;
1230 }
1231 strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
1232 pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
1233 pNewField->mFieldType = pFieldType;
1234 pNewField->mArrayNum = ArrayNum;
1235 pNewField->mIsBitField = FALSE;
1236 if ((mNewDataType->mTotalSize % Align) == 0) {
1237 pNewField->mOffset = mNewDataType->mTotalSize;
1238 } else {
1239 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
1240 }
1241 if (mNewDataType->mMembers == NULL) {
1242 mNewDataType->mMembers = pNewField;
1243 pNewField->mNext = NULL;
1244 } else {
1245 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
1246 ;
1247 pTmp->mNext = pNewField;
1248 pNewField->mNext = NULL;
1249 }
1250
1251 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
1252
1253 if (FieldInUnion) {
1254 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
1255 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
1256 }
1257 pNewField->mOffset = 0;
1258 } else {
1259 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
1260 }
1261
1262 return VFR_RETURN_SUCCESS;
1263 }
1264
1265 VOID
1266 CVfrVarDataTypeDB::DeclareDataTypeEnd (
1267 VOID
1268 )
1269 {
1270 if (mNewDataType->mTypeName[0] == '\0') {
1271 return;
1272 }
1273
1274 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
1275 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
1276 }
1277
1278 RegisterNewType (mNewDataType);
1279 if (mFirstNewDataTypeName == NULL) {
1280 mFirstNewDataTypeName = mNewDataType->mTypeName;
1281 }
1282
1283 mNewDataType = NULL;
1284 }
1285
1286 EFI_VFR_RETURN_CODE
1287 CVfrVarDataTypeDB::GetDataType (
1288 IN CHAR8 *TypeName,
1289 OUT SVfrDataType **DataType
1290 )
1291 {
1292 SVfrDataType *pDataType = NULL;
1293
1294 if (TypeName == NULL) {
1295 return VFR_RETURN_ERROR_SKIPED;
1296 }
1297
1298 if (DataType == NULL) {
1299 return VFR_RETURN_FATAL_ERROR;
1300 }
1301
1302 *DataType = NULL;
1303
1304 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1305 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1306 *DataType = pDataType;
1307 return VFR_RETURN_SUCCESS;
1308 }
1309 }
1310
1311 return VFR_RETURN_UNDEFINED;
1312 }
1313
1314 EFI_VFR_RETURN_CODE
1315 CVfrVarDataTypeDB::GetDataTypeSize (
1316 IN UINT8 DataType,
1317 OUT UINT32 *Size
1318 )
1319 {
1320 SVfrDataType *pDataType = NULL;
1321
1322 if (Size == NULL) {
1323 return VFR_RETURN_FATAL_ERROR;
1324 }
1325
1326 *Size = 0;
1327 DataType = DataType & 0x0F;
1328
1329 //
1330 // For user defined data type, the size can't be got by this function.
1331 //
1332 if (DataType == EFI_IFR_TYPE_OTHER) {
1333 return VFR_RETURN_SUCCESS;
1334 }
1335
1336 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1337 if (DataType == pDataType->mType) {
1338 *Size = pDataType->mTotalSize;
1339 return VFR_RETURN_SUCCESS;
1340 }
1341 }
1342
1343 return VFR_RETURN_UNDEFINED;
1344 }
1345
1346 EFI_VFR_RETURN_CODE
1347 CVfrVarDataTypeDB::GetDataTypeSize (
1348 IN CHAR8 *TypeName,
1349 OUT UINT32 *Size
1350 )
1351 {
1352 SVfrDataType *pDataType = NULL;
1353
1354 if (Size == NULL) {
1355 return VFR_RETURN_FATAL_ERROR;
1356 }
1357
1358 *Size = 0;
1359
1360 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
1361 if (strcmp (TypeName, pDataType->mTypeName) == 0) {
1362 *Size = pDataType->mTotalSize;
1363 return VFR_RETURN_SUCCESS;
1364 }
1365 }
1366
1367 return VFR_RETURN_UNDEFINED;
1368 }
1369
1370 EFI_VFR_RETURN_CODE
1371 CVfrVarDataTypeDB::GetDataFieldInfo (
1372 IN CHAR8 *VarStr,
1373 OUT UINT16 &Offset,
1374 OUT UINT8 &Type,
1375 OUT UINT32 &Size,
1376 OUT BOOLEAN &BitField
1377 )
1378 {
1379 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
1380 UINT32 ArrayIdx, Tmp;
1381 SVfrDataType *pType = NULL;
1382 SVfrDataField *pField = NULL;
1383 CHAR8 *VarStrName;
1384
1385 Offset = 0;
1386 Type = EFI_IFR_TYPE_OTHER;
1387 Size = 0;
1388 VarStrName = VarStr;
1389
1390 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
1391 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
1392
1393 BitField = IsThisBitField (VarStrName);
1394
1395 //
1396 // if it is not struct data type
1397 //
1398 Type = pType->mType;
1399 Size = pType->mTotalSize;
1400
1401 while (*VarStr != '\0') {
1402 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
1403 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
1404 pType = pField->mFieldType;
1405 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);
1406 if (BitField && !pField->mIsBitField) {
1407 Offset = (UINT16) (Offset + Tmp * 8);
1408 } else {
1409 Offset = (UINT16) (Offset + Tmp);
1410 }
1411 Type = GetFieldWidth (pField);
1412 Size = GetFieldSize (pField, ArrayIdx, BitField);
1413 }
1414 return VFR_RETURN_SUCCESS;
1415 }
1416
1417 EFI_VFR_RETURN_CODE
1418 CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
1419 OUT CHAR8 ***NameList,
1420 OUT UINT32 *ListSize
1421 )
1422 {
1423 UINT32 Index;
1424 SVfrDataType *pType;
1425
1426 if ((NameList == NULL) || (ListSize == NULL)) {
1427 return VFR_RETURN_FATAL_ERROR;
1428 }
1429
1430 *NameList = NULL;
1431 *ListSize = 0;
1432
1433 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1434 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1435 (*ListSize)++;
1436 }
1437 }
1438
1439 if (*ListSize == 0) {
1440 return VFR_RETURN_SUCCESS;
1441 }
1442
1443 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
1444 *ListSize = 0;
1445 return VFR_RETURN_OUT_FOR_RESOURCES;
1446 }
1447
1448 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
1449 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
1450 (*NameList)[Index] = pType->mTypeName;
1451 }
1452 }
1453 return VFR_RETURN_SUCCESS;
1454 }
1455
1456 BOOLEAN
1457 CVfrVarDataTypeDB::IsTypeNameDefined (
1458 IN CHAR8 *TypeName
1459 )
1460 {
1461 SVfrDataType *pType;
1462
1463 if (TypeName == NULL) {
1464 return FALSE;
1465 }
1466
1467 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
1468 if (strcmp (pType->mTypeName, TypeName) == 0) {
1469 return TRUE;
1470 }
1471 }
1472
1473 return FALSE;
1474 }
1475
1476 VOID
1477 CVfrVarDataTypeDB::Dump (
1478 IN FILE *File
1479 )
1480 {
1481 SVfrDataType *pTNode;
1482 SVfrDataField *pFNode;
1483
1484 fprintf (File, "\n\n***************************************************************\n");
1485 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
1486 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1487 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1488 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
1489 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1490 if (pFNode->mArrayNum > 0) {
1491 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
1492 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
1493 } else {
1494 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
1495 pFNode->mFieldName, pFNode->mFieldType->mTypeName);
1496 }
1497 }
1498 fprintf (File, "\t\t};\n");
1499 fprintf (File, "---------------------------------------------------------------\n");
1500 }
1501 fprintf (File, "***************************************************************\n");
1502 }
1503
1504 #ifdef CVFR_VARDATATYPEDB_DEBUG
1505 VOID
1506 CVfrVarDataTypeDB::ParserDB (
1507 VOID
1508 )
1509 {
1510 SVfrDataType *pTNode;
1511 SVfrDataField *pFNode;
1512
1513 printf ("***************************************************************\n");
1514 printf ("\t\tmPackAlign = %x\n", mPackAlign);
1515 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
1516 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
1517 printf ("\t\tstruct %s {\n", pTNode->mTypeName);
1518 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
1519 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
1520 }
1521 printf ("\t\t};\n");
1522 printf ("---------------------------------------------------------------\n");
1523 }
1524 printf ("***************************************************************\n");
1525 }
1526 #endif
1527
1528 SVfrVarStorageNode::SVfrVarStorageNode (
1529 IN EFI_GUID *Guid,
1530 IN CHAR8 *StoreName,
1531 IN EFI_VARSTORE_ID VarStoreId,
1532 IN EFI_STRING_ID VarName,
1533 IN UINT32 VarSize,
1534 IN BOOLEAN Flag
1535 )
1536 {
1537 if (Guid != NULL) {
1538 mGuid = *Guid;
1539 } else {
1540 memset (&mGuid, 0, sizeof (EFI_GUID));
1541 }
1542 if (StoreName != NULL) {
1543 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1544 strcpy (mVarStoreName, StoreName);
1545 } else {
1546 mVarStoreName = NULL;
1547 }
1548 mNext = NULL;
1549 mVarStoreId = VarStoreId;
1550 mVarStoreType = EFI_VFR_VARSTORE_EFI;
1551 mStorageInfo.mEfiVar.mEfiVarName = VarName;
1552 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
1553 mAssignedFlag = Flag;
1554 }
1555
1556 SVfrVarStorageNode::SVfrVarStorageNode (
1557 IN EFI_GUID *Guid,
1558 IN CHAR8 *StoreName,
1559 IN EFI_VARSTORE_ID VarStoreId,
1560 IN SVfrDataType *DataType,
1561 IN BOOLEAN BitsVarstore,
1562 IN BOOLEAN Flag
1563 )
1564 {
1565 if (Guid != NULL) {
1566 mGuid = *Guid;
1567 } else {
1568 memset (&mGuid, 0, sizeof (EFI_GUID));
1569 }
1570 if (StoreName != NULL) {
1571 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1572 strcpy (mVarStoreName, StoreName);
1573 } else {
1574 mVarStoreName = NULL;
1575 }
1576 mNext = NULL;
1577 mVarStoreId = VarStoreId;
1578 if (BitsVarstore) {
1579 mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;
1580 } else {
1581 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
1582 }
1583 mStorageInfo.mDataType = DataType;
1584 mAssignedFlag = Flag;
1585 }
1586
1587 SVfrVarStorageNode::SVfrVarStorageNode (
1588 IN CHAR8 *StoreName,
1589 IN EFI_VARSTORE_ID VarStoreId
1590 )
1591 {
1592 memset (&mGuid, 0, sizeof (EFI_GUID));
1593 if (StoreName != NULL) {
1594 mVarStoreName = new CHAR8[strlen(StoreName) + 1];
1595 strcpy (mVarStoreName, StoreName);
1596 } else {
1597 mVarStoreName = NULL;
1598 }
1599 mNext = NULL;
1600 mVarStoreId = VarStoreId;
1601 mVarStoreType = EFI_VFR_VARSTORE_NAME;
1602 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
1603 mStorageInfo.mNameSpace.mTableSize = 0;
1604 mAssignedFlag = FALSE;
1605 }
1606
1607 SVfrVarStorageNode::~SVfrVarStorageNode (
1608 VOID
1609 )
1610 {
1611 if (mVarStoreName != NULL) {
1612 delete[] mVarStoreName;
1613 }
1614
1615 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
1616 delete[] mStorageInfo.mNameSpace.mNameTable;
1617 }
1618 }
1619
1620 CVfrDataStorage::CVfrDataStorage (
1621 VOID
1622 )
1623 {
1624 UINT32 Index;
1625
1626 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1627 mFreeVarStoreIdBitMap[Index] = 0;
1628 }
1629
1630 // Question ID 0 is reserved.
1631 mFreeVarStoreIdBitMap[0] = 0x80000000;
1632
1633 mBufferVarStoreList = NULL;
1634 mEfiVarStoreList = NULL;
1635 mNameVarStoreList = NULL;
1636 mCurrVarStorageNode = NULL;
1637 mNewVarStorageNode = NULL;
1638 mBufferFieldInfoListHead = NULL;
1639 mBufferFieldInfoListTail = NULL;
1640 }
1641
1642 CVfrDataStorage::~CVfrDataStorage (
1643 VOID
1644 )
1645 {
1646 SVfrVarStorageNode *pNode;
1647
1648 while (mBufferVarStoreList != NULL) {
1649 pNode = mBufferVarStoreList;
1650 mBufferVarStoreList = mBufferVarStoreList->mNext;
1651 delete pNode;
1652 }
1653 while (mEfiVarStoreList != NULL) {
1654 pNode = mEfiVarStoreList;
1655 mEfiVarStoreList = mEfiVarStoreList->mNext;
1656 delete pNode;
1657 }
1658 while (mNameVarStoreList != NULL) {
1659 pNode = mNameVarStoreList;
1660 mNameVarStoreList = mNameVarStoreList->mNext;
1661 delete pNode;
1662 }
1663 if (mNewVarStorageNode != NULL) {
1664 delete mNewVarStorageNode;
1665 }
1666 }
1667
1668 EFI_VARSTORE_ID
1669 CVfrDataStorage::GetFreeVarStoreId (
1670 EFI_VFR_VARSTORE_TYPE VarType
1671 )
1672 {
1673 UINT32 Index, Mask, Offset;
1674
1675 Index = 0;
1676
1677 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
1678 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
1679 break;
1680 }
1681 }
1682
1683 if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
1684 return EFI_VARSTORE_ID_INVALID;
1685 }
1686
1687 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
1688 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
1689 mFreeVarStoreIdBitMap[Index] |= Mask;
1690 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
1691 }
1692 }
1693
1694 return EFI_VARSTORE_ID_INVALID;
1695 }
1696
1697 BOOLEAN
1698 CVfrDataStorage::ChekVarStoreIdFree (
1699 IN EFI_VARSTORE_ID VarStoreId
1700 )
1701 {
1702 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1703 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1704
1705 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
1706 }
1707
1708 VOID
1709 CVfrDataStorage::MarkVarStoreIdUsed (
1710 IN EFI_VARSTORE_ID VarStoreId
1711 )
1712 {
1713 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1714 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1715
1716 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
1717 }
1718
1719 VOID
1720 CVfrDataStorage::MarkVarStoreIdUnused (
1721 IN EFI_VARSTORE_ID VarStoreId
1722 )
1723 {
1724 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
1725 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
1726
1727 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
1728 }
1729
1730 EFI_VFR_RETURN_CODE
1731 CVfrDataStorage::DeclareNameVarStoreBegin (
1732 IN CHAR8 *StoreName,
1733 IN EFI_VARSTORE_ID VarStoreId
1734 )
1735 {
1736 SVfrVarStorageNode *pNode = NULL;
1737 EFI_VARSTORE_ID TmpVarStoreId;
1738
1739 if (StoreName == NULL) {
1740 return VFR_RETURN_FATAL_ERROR;
1741 }
1742
1743 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
1744 return VFR_RETURN_REDEFINED;
1745 }
1746
1747 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1748 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
1749 } else {
1750 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1751 return VFR_RETURN_VARSTOREID_REDEFINED;
1752 }
1753 MarkVarStoreIdUsed (VarStoreId);
1754 }
1755
1756 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
1757 return VFR_RETURN_UNDEFINED;
1758 }
1759
1760 mNewVarStorageNode = pNode;
1761
1762 return VFR_RETURN_SUCCESS;
1763 }
1764
1765 EFI_VFR_RETURN_CODE
1766 CVfrDataStorage::NameTableAddItem (
1767 IN EFI_STRING_ID Item
1768 )
1769 {
1770 EFI_VARSTORE_ID *NewTable, *OldTable;
1771 UINT32 TableSize;
1772
1773 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
1774 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
1775
1776 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
1777 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
1778 return VFR_RETURN_OUT_FOR_RESOURCES;
1779 }
1780 memcpy (NewTable, OldTable, TableSize);
1781 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
1782 }
1783
1784 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
1785 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
1786
1787 return VFR_RETURN_SUCCESS;
1788 }
1789
1790 EFI_VFR_RETURN_CODE
1791 CVfrDataStorage::DeclareNameVarStoreEnd (
1792 IN EFI_GUID *Guid
1793 )
1794 {
1795 mNewVarStorageNode->mGuid = *Guid;
1796 mNewVarStorageNode->mNext = mNameVarStoreList;
1797 mNameVarStoreList = mNewVarStorageNode;
1798
1799 mNewVarStorageNode = NULL;
1800
1801 return VFR_RETURN_SUCCESS;
1802 }
1803
1804 EFI_VFR_RETURN_CODE
1805 CVfrDataStorage::DeclareEfiVarStore (
1806 IN CHAR8 *StoreName,
1807 IN EFI_GUID *Guid,
1808 IN EFI_STRING_ID NameStrId,
1809 IN UINT32 VarSize,
1810 IN BOOLEAN Flag
1811 )
1812 {
1813 SVfrVarStorageNode *pNode;
1814 EFI_VARSTORE_ID VarStoreId;
1815
1816 if ((StoreName == NULL) || (Guid == NULL)) {
1817 return VFR_RETURN_FATAL_ERROR;
1818 }
1819
1820 if (VarSize > sizeof (UINT64)) {
1821 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
1822 }
1823
1824 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1825 return VFR_RETURN_REDEFINED;
1826 }
1827
1828 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
1829 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
1830 return VFR_RETURN_OUT_FOR_RESOURCES;
1831 }
1832
1833 pNode->mNext = mEfiVarStoreList;
1834 mEfiVarStoreList = pNode;
1835
1836 return VFR_RETURN_SUCCESS;
1837 }
1838
1839 EFI_VFR_RETURN_CODE
1840 CVfrDataStorage::DeclareBufferVarStore (
1841 IN CHAR8 *StoreName,
1842 IN EFI_GUID *Guid,
1843 IN CVfrVarDataTypeDB *DataTypeDB,
1844 IN CHAR8 *TypeName,
1845 IN EFI_VARSTORE_ID VarStoreId,
1846 IN BOOLEAN IsBitVarStore,
1847 IN BOOLEAN Flag
1848 )
1849 {
1850 SVfrVarStorageNode *pNew = NULL;
1851 SVfrDataType *pDataType = NULL;
1852 EFI_VARSTORE_ID TempVarStoreId;
1853
1854 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
1855 return VFR_RETURN_FATAL_ERROR;
1856 }
1857
1858 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
1859 return VFR_RETURN_REDEFINED;
1860 }
1861
1862 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
1863
1864 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
1865 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
1866 } else {
1867 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
1868 return VFR_RETURN_VARSTOREID_REDEFINED;
1869 }
1870 MarkVarStoreIdUsed (VarStoreId);
1871 }
1872
1873 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {
1874 return VFR_RETURN_OUT_FOR_RESOURCES;
1875 }
1876
1877 pNew->mNext = mBufferVarStoreList;
1878 mBufferVarStoreList = pNew;
1879
1880 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
1881 return VFR_RETURN_FATAL_ERROR;
1882 }
1883
1884 return VFR_RETURN_SUCCESS;
1885 }
1886
1887 EFI_VFR_RETURN_CODE
1888 CVfrDataStorage::GetVarStoreByDataType (
1889 IN CHAR8 *DataTypeName,
1890 OUT SVfrVarStorageNode **VarNode,
1891 IN EFI_GUID *VarGuid
1892 )
1893 {
1894 SVfrVarStorageNode *pNode;
1895 SVfrVarStorageNode *MatchNode;
1896
1897 MatchNode = NULL;
1898 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1899 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
1900 continue;
1901 }
1902
1903 if ((VarGuid != NULL)) {
1904 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1905 *VarNode = pNode;
1906 return VFR_RETURN_SUCCESS;
1907 }
1908 } else {
1909 if (MatchNode == NULL) {
1910 MatchNode = pNode;
1911 } else {
1912 //
1913 // More than one varstores referred the same data structures.
1914 //
1915 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
1916 }
1917 }
1918 }
1919
1920 if (MatchNode == NULL) {
1921 return VFR_RETURN_UNDEFINED;
1922 }
1923
1924 *VarNode = MatchNode;
1925 return VFR_RETURN_SUCCESS;
1926 }
1927
1928 EFI_VARSTORE_ID
1929 CVfrDataStorage::CheckGuidField (
1930 IN SVfrVarStorageNode *pNode,
1931 IN EFI_GUID *StoreGuid,
1932 IN BOOLEAN *HasFoundOne,
1933 OUT EFI_VFR_RETURN_CODE *ReturnCode
1934 )
1935 {
1936 if (StoreGuid != NULL) {
1937 //
1938 // If has guid info, compare the guid filed.
1939 //
1940 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
1941 //
1942 // Both name and guid are same, this this varstore.
1943 //
1944 mCurrVarStorageNode = pNode;
1945 *ReturnCode = VFR_RETURN_SUCCESS;
1946 return TRUE;
1947 }
1948 } else {
1949 //
1950 // Not has Guid field, check whether this name is the only one.
1951 //
1952 if (*HasFoundOne) {
1953 //
1954 // The name has conflict, return name redefined.
1955 //
1956 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
1957 return TRUE;
1958 }
1959
1960 *HasFoundOne = TRUE;
1961 mCurrVarStorageNode = pNode;
1962 }
1963
1964 return FALSE;
1965 }
1966
1967 /**
1968 Base on the input store name and guid to find the varstore id.
1969
1970 If both name and guid are inputed, base on the name and guid to
1971 found the varstore. If only name inputed, base on the name to
1972 found the varstore and go on to check whether more than one varstore
1973 has the same name. If only has found one varstore, return this
1974 varstore; if more than one varstore has same name, return varstore
1975 name redefined error. If no varstore found by varstore name, call
1976 function GetVarStoreByDataType and use inputed varstore name as
1977 data type name to search.
1978 **/
1979 EFI_VFR_RETURN_CODE
1980 CVfrDataStorage::GetVarStoreId (
1981 IN CHAR8 *StoreName,
1982 OUT EFI_VARSTORE_ID *VarStoreId,
1983 IN EFI_GUID *StoreGuid
1984 )
1985 {
1986 EFI_VFR_RETURN_CODE ReturnCode;
1987 SVfrVarStorageNode *pNode;
1988 BOOLEAN HasFoundOne = FALSE;
1989
1990 mCurrVarStorageNode = NULL;
1991
1992 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
1993 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
1994 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
1995 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
1996 return ReturnCode;
1997 }
1998 }
1999 }
2000
2001 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2002 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
2003 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
2004 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2005 return ReturnCode;
2006 }
2007 }
2008 }
2009
2010 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2011 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
2012 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
2013 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2014 return ReturnCode;
2015 }
2016 }
2017 }
2018
2019 if (HasFoundOne) {
2020 *VarStoreId = mCurrVarStorageNode->mVarStoreId;
2021 return VFR_RETURN_SUCCESS;
2022 }
2023
2024 *VarStoreId = EFI_VARSTORE_ID_INVALID;
2025
2026 //
2027 // Assume that Data structure name is used as StoreName, and check again.
2028 //
2029 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
2030 if (pNode != NULL) {
2031 mCurrVarStorageNode = pNode;
2032 *VarStoreId = pNode->mVarStoreId;
2033 }
2034
2035 return ReturnCode;
2036 }
2037
2038 EFI_VFR_RETURN_CODE
2039 CVfrDataStorage::GetBufferVarStoreDataTypeName (
2040 IN EFI_VARSTORE_ID VarStoreId,
2041 OUT CHAR8 **DataTypeName
2042 )
2043 {
2044 SVfrVarStorageNode *pNode;
2045
2046 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2047 return VFR_RETURN_FATAL_ERROR;
2048 }
2049
2050 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2051 if (pNode->mVarStoreId == VarStoreId) {
2052 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
2053 return VFR_RETURN_SUCCESS;
2054 }
2055 }
2056
2057 return VFR_RETURN_UNDEFINED;
2058 }
2059
2060 EFI_VFR_VARSTORE_TYPE
2061 CVfrDataStorage::GetVarStoreType (
2062 IN EFI_VARSTORE_ID VarStoreId
2063 )
2064 {
2065 SVfrVarStorageNode *pNode;
2066 EFI_VFR_VARSTORE_TYPE VarStoreType;
2067
2068 VarStoreType = EFI_VFR_VARSTORE_INVALID;
2069
2070 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2071 return VarStoreType;
2072 }
2073
2074 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2075 if (pNode->mVarStoreId == VarStoreId) {
2076 VarStoreType = pNode->mVarStoreType;
2077 return VarStoreType;
2078 }
2079 }
2080
2081 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2082 if (pNode->mVarStoreId == VarStoreId) {
2083 VarStoreType = pNode->mVarStoreType;
2084 return VarStoreType;
2085 }
2086 }
2087
2088 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2089 if (pNode->mVarStoreId == VarStoreId) {
2090 VarStoreType = pNode->mVarStoreType;
2091 return VarStoreType;
2092 }
2093 }
2094
2095 return VarStoreType;
2096 }
2097
2098 EFI_GUID *
2099 CVfrDataStorage::GetVarStoreGuid (
2100 IN EFI_VARSTORE_ID VarStoreId
2101 )
2102 {
2103 SVfrVarStorageNode *pNode;
2104 EFI_GUID *VarGuid;
2105
2106 VarGuid = NULL;
2107
2108 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
2109 return VarGuid;
2110 }
2111
2112 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2113 if (pNode->mVarStoreId == VarStoreId) {
2114 VarGuid = &pNode->mGuid;
2115 return VarGuid;
2116 }
2117 }
2118
2119 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2120 if (pNode->mVarStoreId == VarStoreId) {
2121 VarGuid = &pNode->mGuid;
2122 return VarGuid;
2123 }
2124 }
2125
2126 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2127 if (pNode->mVarStoreId == VarStoreId) {
2128 VarGuid = &pNode->mGuid;
2129 return VarGuid;
2130 }
2131 }
2132
2133 return VarGuid;
2134 }
2135
2136 EFI_VFR_RETURN_CODE
2137 CVfrDataStorage::GetVarStoreName (
2138 IN EFI_VARSTORE_ID VarStoreId,
2139 OUT CHAR8 **VarStoreName
2140 )
2141 {
2142 SVfrVarStorageNode *pNode;
2143
2144 if (VarStoreName == NULL) {
2145 return VFR_RETURN_FATAL_ERROR;
2146 }
2147
2148 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2149 if (pNode->mVarStoreId == VarStoreId) {
2150 *VarStoreName = pNode->mVarStoreName;
2151 return VFR_RETURN_SUCCESS;
2152 }
2153 }
2154
2155 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2156 if (pNode->mVarStoreId == VarStoreId) {
2157 *VarStoreName = pNode->mVarStoreName;
2158 return VFR_RETURN_SUCCESS;
2159 }
2160 }
2161
2162 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
2163 if (pNode->mVarStoreId == VarStoreId) {
2164 *VarStoreName = pNode->mVarStoreName;
2165 return VFR_RETURN_SUCCESS;
2166 }
2167 }
2168
2169 *VarStoreName = NULL;
2170 return VFR_RETURN_UNDEFINED;
2171 }
2172
2173 EFI_VFR_RETURN_CODE
2174 CVfrDataStorage::GetEfiVarStoreInfo (
2175 IN OUT EFI_VARSTORE_INFO *Info
2176 )
2177 {
2178 if (Info == NULL) {
2179 return VFR_RETURN_FATAL_ERROR;
2180 }
2181
2182 if (mCurrVarStorageNode == NULL) {
2183 return VFR_RETURN_GET_EFIVARSTORE_ERROR;
2184 }
2185
2186 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
2187 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
2188 switch (Info->mVarTotalSize) {
2189 case 1:
2190 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
2191 break;
2192 case 2:
2193 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
2194 break;
2195 case 4:
2196 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
2197 break;
2198 case 8:
2199 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
2200 break;
2201 default :
2202 return VFR_RETURN_FATAL_ERROR;
2203 }
2204
2205 return VFR_RETURN_SUCCESS;
2206 }
2207
2208 EFI_VFR_RETURN_CODE
2209 CVfrDataStorage::AddBufferVarStoreFieldInfo (
2210 IN EFI_VARSTORE_INFO *Info
2211 )
2212 {
2213 BufferVarStoreFieldInfoNode *pNew;
2214
2215 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
2216 return VFR_RETURN_FATAL_ERROR;
2217 }
2218
2219 if (mBufferFieldInfoListHead == NULL) {
2220 mBufferFieldInfoListHead = pNew;
2221 mBufferFieldInfoListTail= pNew;
2222 } else {
2223 mBufferFieldInfoListTail->mNext = pNew;
2224 mBufferFieldInfoListTail = pNew;
2225 }
2226
2227 return VFR_RETURN_SUCCESS;
2228 }
2229
2230 EFI_VFR_RETURN_CODE
2231 CVfrDataStorage::GetBufferVarStoreFieldInfo (
2232 IN OUT EFI_VARSTORE_INFO *Info
2233 )
2234 {
2235 BufferVarStoreFieldInfoNode *pNode;
2236
2237 pNode = mBufferFieldInfoListHead;
2238 while (pNode != NULL) {
2239 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
2240 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
2241 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
2242 Info->mVarType = pNode->mVarStoreInfo.mVarType;
2243 return VFR_RETURN_SUCCESS;
2244 }
2245 pNode = pNode->mNext;
2246 }
2247 return VFR_RETURN_FATAL_ERROR;
2248 }
2249
2250 EFI_VFR_RETURN_CODE
2251 CVfrDataStorage::GetNameVarStoreInfo (
2252 OUT EFI_VARSTORE_INFO *Info,
2253 IN UINT32 Index
2254 )
2255 {
2256 if (Info == NULL) {
2257 return VFR_RETURN_FATAL_ERROR;
2258 }
2259
2260 if (mCurrVarStorageNode == NULL) {
2261 return VFR_RETURN_GET_NVVARSTORE_ERROR;
2262 }
2263
2264 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
2265
2266 return VFR_RETURN_SUCCESS;
2267 }
2268
2269 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
2270 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
2271 IN CHAR8 *RefName,
2272 IN EFI_STRING_ID DefaultStoreNameId,
2273 IN UINT16 DefaultId
2274 )
2275 {
2276 mObjBinAddr = ObjBinAddr;
2277
2278 if (RefName != NULL) {
2279 mRefName = new CHAR8[strlen (RefName) + 1];
2280 strcpy (mRefName, RefName);
2281 } else {
2282 mRefName = NULL;
2283 }
2284
2285 mNext = NULL;
2286 mDefaultId = DefaultId;
2287 mDefaultStoreNameId = DefaultStoreNameId;
2288 }
2289
2290 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
2291 VOID
2292 )
2293 {
2294 if (mRefName != NULL) {
2295 delete[] mRefName;
2296 }
2297 }
2298
2299 CVfrDefaultStore::CVfrDefaultStore (
2300 VOID
2301 )
2302 {
2303 mDefaultStoreList = NULL;
2304 }
2305
2306 CVfrDefaultStore::~CVfrDefaultStore (
2307 VOID
2308 )
2309 {
2310 SVfrDefaultStoreNode *pTmp = NULL;
2311
2312 while (mDefaultStoreList != NULL) {
2313 pTmp = mDefaultStoreList;
2314 mDefaultStoreList = mDefaultStoreList->mNext;
2315 delete pTmp;
2316 }
2317 }
2318
2319 EFI_VFR_RETURN_CODE
2320 CVfrDefaultStore::RegisterDefaultStore (
2321 IN CHAR8 *ObjBinAddr,
2322 IN CHAR8 *RefName,
2323 IN EFI_STRING_ID DefaultStoreNameId,
2324 IN UINT16 DefaultId
2325 )
2326 {
2327 SVfrDefaultStoreNode *pNode = NULL;
2328
2329 if (RefName == NULL) {
2330 return VFR_RETURN_FATAL_ERROR;
2331 }
2332
2333 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2334 if (strcmp (pNode->mRefName, RefName) == 0) {
2335 return VFR_RETURN_REDEFINED;
2336 }
2337 }
2338
2339 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
2340 return VFR_RETURN_OUT_FOR_RESOURCES;
2341 }
2342
2343 pNode->mNext = mDefaultStoreList;
2344 mDefaultStoreList = pNode;
2345
2346 return VFR_RETURN_SUCCESS;
2347 }
2348
2349 /*
2350 * assign new reference name or new default store name id only if
2351 * the original is invalid
2352 */
2353 EFI_VFR_RETURN_CODE
2354 CVfrDefaultStore::ReRegisterDefaultStoreById (
2355 IN UINT16 DefaultId,
2356 IN CHAR8 *RefName,
2357 IN EFI_STRING_ID DefaultStoreNameId
2358 )
2359 {
2360 SVfrDefaultStoreNode *pNode = NULL;
2361
2362 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2363 if (pNode->mDefaultId == DefaultId) {
2364 break;
2365 }
2366 }
2367
2368 if (pNode == NULL) {
2369 return VFR_RETURN_UNDEFINED;
2370 } else {
2371 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
2372 pNode->mDefaultStoreNameId = DefaultStoreNameId;
2373 if (pNode->mObjBinAddr != NULL) {
2374 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
2375 }
2376 } else {
2377 return VFR_RETURN_REDEFINED;
2378 }
2379
2380 if (RefName != NULL) {
2381 delete pNode->mRefName;
2382 pNode->mRefName = new CHAR8[strlen (RefName) + 1];
2383 if (pNode->mRefName != NULL) {
2384 strcpy (pNode->mRefName, RefName);
2385 }
2386 }
2387 }
2388
2389 return VFR_RETURN_SUCCESS;
2390 }
2391
2392 BOOLEAN
2393 CVfrDefaultStore::DefaultIdRegistered (
2394 IN UINT16 DefaultId
2395 )
2396 {
2397 SVfrDefaultStoreNode *pNode = NULL;
2398
2399 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2400 if (pNode->mDefaultId == DefaultId) {
2401 return TRUE;
2402 }
2403 }
2404
2405 return FALSE;
2406 }
2407
2408 EFI_VFR_RETURN_CODE
2409 CVfrDefaultStore::GetDefaultId (
2410 IN CHAR8 *RefName,
2411 OUT UINT16 *DefaultId
2412 )
2413 {
2414 SVfrDefaultStoreNode *pTmp = NULL;
2415
2416 if (DefaultId == NULL) {
2417 return VFR_RETURN_FATAL_ERROR;
2418 }
2419
2420 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
2421 if (strcmp (pTmp->mRefName, RefName) == 0) {
2422 *DefaultId = pTmp->mDefaultId;
2423 return VFR_RETURN_SUCCESS;
2424 }
2425 }
2426
2427 return VFR_RETURN_UNDEFINED;
2428 }
2429
2430 EFI_VFR_RETURN_CODE
2431 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
2432 IN EFI_VARSTORE_ID DefaultId,
2433 IN EFI_VARSTORE_INFO &Info,
2434 IN CHAR8 *VarStoreName,
2435 IN EFI_GUID *VarStoreGuid,
2436 IN UINT8 Type,
2437 IN EFI_IFR_TYPE_VALUE Value
2438 )
2439 {
2440 SVfrDefaultStoreNode *pNode = NULL;
2441 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
2442 INTN Returnvalue = 0;
2443
2444 if (VarStoreName == NULL) {
2445 return VFR_RETURN_FATAL_ERROR;
2446 }
2447
2448 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
2449 if (pNode->mDefaultId == DefaultId) {
2450 break;
2451 }
2452 }
2453
2454 if (pNode == NULL) {
2455 return VFR_RETURN_UNDEFINED;
2456 }
2457
2458 gCVfrBufferConfig.Open ();
2459
2460 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
2461 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
2462 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
2463 goto WriteError;
2464 }
2465 }
2466
2467 gCVfrBufferConfig.Close ();
2468
2469 return VFR_RETURN_SUCCESS;
2470
2471 WriteError:
2472 gCVfrBufferConfig.Close ();
2473 return (EFI_VFR_RETURN_CODE)Returnvalue;
2474 }
2475
2476 SVfrRuleNode::SVfrRuleNode (
2477 IN CHAR8 *RuleName,
2478 IN UINT8 RuleId
2479 )
2480 {
2481 if (RuleName != NULL) {
2482 mRuleName = new CHAR8[strlen (RuleName) + 1];
2483 strcpy (mRuleName, RuleName);
2484 } else {
2485 mRuleName = NULL;
2486 }
2487
2488 mNext = NULL;
2489 mRuleId = RuleId;
2490 }
2491
2492 SVfrRuleNode::~SVfrRuleNode (
2493 VOID
2494 )
2495 {
2496 if (mRuleName != NULL) {
2497 delete[] mRuleName;
2498 }
2499 }
2500
2501 CVfrRulesDB::CVfrRulesDB ()
2502 {
2503 mRuleList = NULL;
2504 mFreeRuleId = EFI_VARSTORE_ID_START;
2505 }
2506
2507 CVfrRulesDB::~CVfrRulesDB ()
2508 {
2509 SVfrRuleNode *pNode;
2510
2511 while(mRuleList != NULL) {
2512 pNode = mRuleList;
2513 mRuleList = mRuleList->mNext;
2514 delete pNode;
2515 }
2516 }
2517
2518 VOID
2519 CVfrRulesDB::RegisterRule (
2520 IN CHAR8 *RuleName
2521 )
2522 {
2523 SVfrRuleNode *pNew;
2524
2525 if (RuleName == NULL) {
2526 return ;
2527 }
2528
2529 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
2530 return ;
2531 }
2532
2533 mFreeRuleId++;
2534
2535 pNew->mNext = mRuleList;
2536 mRuleList = pNew;
2537 }
2538
2539 UINT8
2540 CVfrRulesDB::GetRuleId (
2541 IN CHAR8 *RuleName
2542 )
2543 {
2544 SVfrRuleNode *pNode;
2545
2546 if (RuleName == NULL) {
2547 return EFI_RULE_ID_INVALID;
2548 }
2549
2550 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
2551 if (strcmp (pNode->mRuleName, RuleName) == 0) {
2552 return pNode->mRuleId;
2553 }
2554 }
2555
2556 return EFI_RULE_ID_INVALID;
2557 }
2558
2559 CVfrRulesDB gCVfrRulesDB;
2560
2561 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2562 VOID
2563 )
2564 {
2565 mVarStoreId = EFI_VARSTORE_ID_INVALID;
2566 mInfo.mVarName = EFI_STRING_ID_INVALID;
2567 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2568 mVarType = EFI_IFR_TYPE_OTHER;
2569 mVarTotalSize = 0;
2570 mIsBitVar = FALSE;
2571 }
2572
2573 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
2574 IN EFI_VARSTORE_INFO &Info
2575 )
2576 {
2577 mVarStoreId = Info.mVarStoreId;
2578 mInfo.mVarName = Info.mInfo.mVarName;
2579 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2580 mVarType = Info.mVarType;
2581 mVarTotalSize = Info.mVarTotalSize;
2582 mIsBitVar = Info.mIsBitVar;
2583 }
2584
2585 EFI_VARSTORE_INFO&
2586 EFI_VARSTORE_INFO::operator= (
2587 IN CONST EFI_VARSTORE_INFO &Info
2588 )
2589 {
2590 if (this != &Info) {
2591 mVarStoreId = Info.mVarStoreId;
2592 mInfo.mVarName = Info.mInfo.mVarName;
2593 mInfo.mVarOffset = Info.mInfo.mVarOffset;
2594 mVarType = Info.mVarType;
2595 mVarTotalSize = Info.mVarTotalSize;
2596 mIsBitVar = Info.mIsBitVar;
2597 }
2598
2599 return *this;
2600 }
2601
2602 BOOLEAN
2603 EFI_VARSTORE_INFO::operator == (
2604 IN EFI_VARSTORE_INFO *Info
2605 )
2606 {
2607 if ((mVarStoreId == Info->mVarStoreId) &&
2608 (mInfo.mVarName == Info->mInfo.mVarName) &&
2609 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
2610 (mVarType == Info->mVarType) &&
2611 (mVarTotalSize == Info->mVarTotalSize) &&
2612 (mIsBitVar == Info->mIsBitVar)) {
2613 return TRUE;
2614 }
2615
2616 return FALSE;
2617 }
2618
2619 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
2620 IN EFI_VARSTORE_INFO *Info
2621 )
2622 {
2623 mVarStoreInfo.mVarType = Info->mVarType;
2624 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
2625 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
2626 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
2627 mNext = NULL;
2628 }
2629
2630 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
2631 {
2632 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
2633 mVarStoreInfo.mVarTotalSize = 0;
2634 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
2635 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
2636 mNext = NULL;
2637 }
2638
2639 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
2640
2641 EFI_QUESTION_ID
2642 CVfrQuestionDB::GetFreeQuestionId (
2643 VOID
2644 )
2645 {
2646 UINT32 Index, Mask, Offset;
2647
2648 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2649 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
2650 break;
2651 }
2652 }
2653
2654 if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
2655 return EFI_QUESTION_ID_INVALID;
2656 }
2657
2658 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
2659 if ((mFreeQIdBitMap[Index] & Mask) == 0) {
2660 mFreeQIdBitMap[Index] |= Mask;
2661 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
2662 }
2663 }
2664
2665 return EFI_QUESTION_ID_INVALID;
2666 }
2667
2668 BOOLEAN
2669 CVfrQuestionDB::ChekQuestionIdFree (
2670 IN EFI_QUESTION_ID QId
2671 )
2672 {
2673 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2674 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2675
2676 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
2677 }
2678
2679 VOID
2680 CVfrQuestionDB::MarkQuestionIdUsed (
2681 IN EFI_QUESTION_ID QId
2682 )
2683 {
2684 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2685 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2686
2687 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
2688 }
2689
2690 VOID
2691 CVfrQuestionDB::MarkQuestionIdUnused (
2692 IN EFI_QUESTION_ID QId
2693 )
2694 {
2695 UINT32 Index = (QId / EFI_BITS_PER_UINT32);
2696 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
2697
2698 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
2699 }
2700
2701 SVfrQuestionNode::SVfrQuestionNode (
2702 IN CHAR8 *Name,
2703 IN CHAR8 *VarIdStr,
2704 IN UINT32 BitMask
2705 )
2706 {
2707 mName = NULL;
2708 mVarIdStr = NULL;
2709 mQuestionId = EFI_QUESTION_ID_INVALID;
2710 mBitMask = BitMask;
2711 mNext = NULL;
2712 mQtype = QUESTION_NORMAL;
2713
2714 if (Name == NULL) {
2715 mName = new CHAR8[strlen ("$DEFAULT") + 1];
2716 strcpy (mName, "$DEFAULT");
2717 } else {
2718 mName = new CHAR8[strlen (Name) + 1];
2719 strcpy (mName, Name);
2720 }
2721
2722 if (VarIdStr != NULL) {
2723 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
2724 strcpy (mVarIdStr, VarIdStr);
2725 } else {
2726 mVarIdStr = new CHAR8[strlen ("$") + 1];
2727 strcpy (mVarIdStr, "$");
2728 }
2729 }
2730
2731 SVfrQuestionNode::~SVfrQuestionNode (
2732 VOID
2733 )
2734 {
2735 if (mName != NULL) {
2736 delete[] mName;
2737 }
2738
2739 if (mVarIdStr != NULL) {
2740 delete[] mVarIdStr;
2741 }
2742 }
2743
2744 CVfrQuestionDB::CVfrQuestionDB ()
2745 {
2746 UINT32 Index;
2747
2748 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2749 mFreeQIdBitMap[Index] = 0;
2750 }
2751
2752 // Question ID 0 is reserved.
2753 mFreeQIdBitMap[0] = 0x80000000;
2754 mQuestionList = NULL;
2755 }
2756
2757 CVfrQuestionDB::~CVfrQuestionDB ()
2758 {
2759 SVfrQuestionNode *pNode;
2760
2761 while (mQuestionList != NULL) {
2762 pNode = mQuestionList;
2763 mQuestionList = mQuestionList->mNext;
2764 delete pNode;
2765 }
2766 }
2767
2768 //
2769 // Reset to init state
2770 //
2771 VOID
2772 CVfrQuestionDB::ResetInit(
2773 IN VOID
2774 )
2775 {
2776 UINT32 Index;
2777 SVfrQuestionNode *pNode;
2778
2779 while (mQuestionList != NULL) {
2780 pNode = mQuestionList;
2781 mQuestionList = mQuestionList->mNext;
2782 delete pNode;
2783 }
2784
2785 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
2786 mFreeQIdBitMap[Index] = 0;
2787 }
2788
2789 // Question ID 0 is reserved.
2790 mFreeQIdBitMap[0] = 0x80000000;
2791 mQuestionList = NULL;
2792 }
2793
2794 VOID
2795 CVfrQuestionDB::PrintAllQuestion (
2796 VOID
2797 )
2798 {
2799 SVfrQuestionNode *pNode = NULL;
2800
2801 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
2802 printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
2803 }
2804 }
2805
2806 EFI_VFR_RETURN_CODE
2807 CVfrQuestionDB::RegisterQuestion (
2808 IN CHAR8 *Name,
2809 IN CHAR8 *VarIdStr,
2810 IN OUT EFI_QUESTION_ID &QuestionId
2811 )
2812 {
2813 SVfrQuestionNode *pNode = NULL;
2814
2815 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
2816 return VFR_RETURN_REDEFINED;
2817 }
2818
2819 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
2820 return VFR_RETURN_OUT_FOR_RESOURCES;
2821 }
2822
2823 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2824 QuestionId = GetFreeQuestionId ();
2825 } else {
2826 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2827 delete pNode;
2828 return VFR_RETURN_QUESTIONID_REDEFINED;
2829 }
2830 MarkQuestionIdUsed (QuestionId);
2831 }
2832 pNode->mQuestionId = QuestionId;
2833
2834 pNode->mNext = mQuestionList;
2835 mQuestionList = pNode;
2836
2837 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2838
2839 return VFR_RETURN_SUCCESS;
2840 }
2841
2842 VOID
2843 CVfrQuestionDB::RegisterOldDateQuestion (
2844 IN CHAR8 *YearVarId,
2845 IN CHAR8 *MonthVarId,
2846 IN CHAR8 *DayVarId,
2847 IN OUT EFI_QUESTION_ID &QuestionId
2848 )
2849 {
2850 SVfrQuestionNode *pNode[3] = {NULL, };
2851 UINT32 Index;
2852
2853 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
2854 return;
2855 }
2856
2857 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
2858 goto Err;
2859 }
2860 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
2861 goto Err;
2862 }
2863 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
2864 goto Err;
2865 }
2866
2867 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2868 QuestionId = GetFreeQuestionId ();
2869 } else {
2870 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2871 goto Err;
2872 }
2873 MarkQuestionIdUsed (QuestionId);
2874 }
2875
2876 pNode[0]->mQuestionId = QuestionId;
2877 pNode[1]->mQuestionId = QuestionId;
2878 pNode[2]->mQuestionId = QuestionId;
2879 pNode[0]->mQtype = QUESTION_DATE;
2880 pNode[1]->mQtype = QUESTION_DATE;
2881 pNode[2]->mQtype = QUESTION_DATE;
2882 pNode[0]->mNext = pNode[1];
2883 pNode[1]->mNext = pNode[2];
2884 pNode[2]->mNext = mQuestionList;
2885 mQuestionList = pNode[0];
2886
2887 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2888 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2889 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
2890
2891 return;
2892
2893 Err:
2894 for (Index = 0; Index < 3; Index++) {
2895 if (pNode[Index] != NULL) {
2896 delete pNode[Index];
2897 }
2898 }
2899 QuestionId = EFI_QUESTION_ID_INVALID;
2900 }
2901
2902 VOID
2903 CVfrQuestionDB::RegisterNewDateQuestion (
2904 IN CHAR8 *Name,
2905 IN CHAR8 *BaseVarId,
2906 IN OUT EFI_QUESTION_ID &QuestionId
2907 )
2908 {
2909 SVfrQuestionNode *pNode[3] = {NULL, };
2910 UINT32 Len;
2911 CHAR8 *VarIdStr[3] = {NULL, };
2912 CHAR8 Index;
2913
2914 if (BaseVarId == NULL && Name == NULL) {
2915 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2916 QuestionId = GetFreeQuestionId ();
2917 } else {
2918 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2919 goto Err;
2920 }
2921 MarkQuestionIdUsed (QuestionId);
2922 }
2923 return;
2924 }
2925
2926 if (BaseVarId != NULL) {
2927 Len = strlen (BaseVarId);
2928
2929 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2930 if (VarIdStr[0] != NULL) {
2931 strcpy (VarIdStr[0], BaseVarId);
2932 strcat (VarIdStr[0], ".Year");
2933 }
2934 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2935 if (VarIdStr[1] != NULL) {
2936 strcpy (VarIdStr[1], BaseVarId);
2937 strcat (VarIdStr[1], ".Month");
2938 }
2939 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2940 if (VarIdStr[2] != NULL) {
2941 strcpy (VarIdStr[2], BaseVarId);
2942 strcat (VarIdStr[2], ".Day");
2943 }
2944 } else {
2945 Len = strlen (Name);
2946
2947 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
2948 if (VarIdStr[0] != NULL) {
2949 strcpy (VarIdStr[0], Name);
2950 strcat (VarIdStr[0], ".Year");
2951 }
2952 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
2953 if (VarIdStr[1] != NULL) {
2954 strcpy (VarIdStr[1], Name);
2955 strcat (VarIdStr[1], ".Month");
2956 }
2957 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
2958 if (VarIdStr[2] != NULL) {
2959 strcpy (VarIdStr[2], Name);
2960 strcat (VarIdStr[2], ".Day");
2961 }
2962 }
2963
2964 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
2965 goto Err;
2966 }
2967 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
2968 goto Err;
2969 }
2970 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
2971 goto Err;
2972 }
2973
2974 if (QuestionId == EFI_QUESTION_ID_INVALID) {
2975 QuestionId = GetFreeQuestionId ();
2976 } else {
2977 if (ChekQuestionIdFree (QuestionId) == FALSE) {
2978 goto Err;
2979 }
2980 MarkQuestionIdUsed (QuestionId);
2981 }
2982
2983 pNode[0]->mQuestionId = QuestionId;
2984 pNode[1]->mQuestionId = QuestionId;
2985 pNode[2]->mQuestionId = QuestionId;
2986 pNode[0]->mQtype = QUESTION_DATE;
2987 pNode[1]->mQtype = QUESTION_DATE;
2988 pNode[2]->mQtype = QUESTION_DATE;
2989 pNode[0]->mNext = pNode[1];
2990 pNode[1]->mNext = pNode[2];
2991 pNode[2]->mNext = mQuestionList;
2992 mQuestionList = pNode[0];
2993
2994 for (Index = 0; Index < 3; Index++) {
2995 if (VarIdStr[Index] != NULL) {
2996 delete[] VarIdStr[Index];
2997 VarIdStr[Index] = NULL;
2998 }
2999 }
3000
3001 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3002 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3003 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3004
3005 return;
3006
3007 Err:
3008 for (Index = 0; Index < 3; Index++) {
3009 if (pNode[Index] != NULL) {
3010 delete pNode[Index];
3011 }
3012
3013 if (VarIdStr[Index] != NULL) {
3014 delete[] VarIdStr [Index];
3015 VarIdStr [Index] = NULL;
3016 }
3017 }
3018 }
3019
3020 VOID
3021 CVfrQuestionDB::RegisterOldTimeQuestion (
3022 IN CHAR8 *HourVarId,
3023 IN CHAR8 *MinuteVarId,
3024 IN CHAR8 *SecondVarId,
3025 IN OUT EFI_QUESTION_ID &QuestionId
3026 )
3027 {
3028 SVfrQuestionNode *pNode[3] = {NULL, };
3029 UINT32 Index;
3030
3031 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
3032 return;
3033 }
3034
3035 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
3036 goto Err;
3037 }
3038 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
3039 goto Err;
3040 }
3041 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
3042 goto Err;
3043 }
3044
3045 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3046 QuestionId = GetFreeQuestionId ();
3047 } else {
3048 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3049 goto Err;
3050 }
3051 MarkQuestionIdUsed (QuestionId);
3052 }
3053
3054 pNode[0]->mQuestionId = QuestionId;
3055 pNode[1]->mQuestionId = QuestionId;
3056 pNode[2]->mQuestionId = QuestionId;
3057 pNode[0]->mQtype = QUESTION_TIME;
3058 pNode[1]->mQtype = QUESTION_TIME;
3059 pNode[2]->mQtype = QUESTION_TIME;
3060 pNode[0]->mNext = pNode[1];
3061 pNode[1]->mNext = pNode[2];
3062 pNode[2]->mNext = mQuestionList;
3063 mQuestionList = pNode[0];
3064
3065 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3066 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3067 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3068
3069 return;
3070
3071 Err:
3072 for (Index = 0; Index < 3; Index++) {
3073 if (pNode[Index] != NULL) {
3074 delete pNode[Index];
3075 }
3076 }
3077 QuestionId = EFI_QUESTION_ID_INVALID;
3078 }
3079
3080 VOID
3081 CVfrQuestionDB::RegisterNewTimeQuestion (
3082 IN CHAR8 *Name,
3083 IN CHAR8 *BaseVarId,
3084 IN OUT EFI_QUESTION_ID &QuestionId
3085 )
3086 {
3087 SVfrQuestionNode *pNode[3] = {NULL, };
3088 UINT32 Len;
3089 CHAR8 *VarIdStr[3] = {NULL, };
3090 CHAR8 Index;
3091
3092 if (BaseVarId == NULL && Name == NULL) {
3093 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3094 QuestionId = GetFreeQuestionId ();
3095 } else {
3096 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3097 goto Err;
3098 }
3099 MarkQuestionIdUsed (QuestionId);
3100 }
3101 return;
3102 }
3103
3104 if (BaseVarId != NULL) {
3105 Len = strlen (BaseVarId);
3106
3107 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
3108 if (VarIdStr[0] != NULL) {
3109 strcpy (VarIdStr[0], BaseVarId);
3110 strcat (VarIdStr[0], ".Hour");
3111 }
3112 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
3113 if (VarIdStr[1] != NULL) {
3114 strcpy (VarIdStr[1], BaseVarId);
3115 strcat (VarIdStr[1], ".Minute");
3116 }
3117 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
3118 if (VarIdStr[2] != NULL) {
3119 strcpy (VarIdStr[2], BaseVarId);
3120 strcat (VarIdStr[2], ".Second");
3121 }
3122 } else {
3123 Len = strlen (Name);
3124
3125 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
3126 if (VarIdStr[0] != NULL) {
3127 strcpy (VarIdStr[0], Name);
3128 strcat (VarIdStr[0], ".Hour");
3129 }
3130 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
3131 if (VarIdStr[1] != NULL) {
3132 strcpy (VarIdStr[1], Name);
3133 strcat (VarIdStr[1], ".Minute");
3134 }
3135 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
3136 if (VarIdStr[2] != NULL) {
3137 strcpy (VarIdStr[2], Name);
3138 strcat (VarIdStr[2], ".Second");
3139 }
3140 }
3141
3142 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
3143 goto Err;
3144 }
3145 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
3146 goto Err;
3147 }
3148 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
3149 goto Err;
3150 }
3151
3152 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3153 QuestionId = GetFreeQuestionId ();
3154 } else {
3155 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3156 goto Err;
3157 }
3158 MarkQuestionIdUsed (QuestionId);
3159 }
3160
3161 pNode[0]->mQuestionId = QuestionId;
3162 pNode[1]->mQuestionId = QuestionId;
3163 pNode[2]->mQuestionId = QuestionId;
3164 pNode[0]->mQtype = QUESTION_TIME;
3165 pNode[1]->mQtype = QUESTION_TIME;
3166 pNode[2]->mQtype = QUESTION_TIME;
3167 pNode[0]->mNext = pNode[1];
3168 pNode[1]->mNext = pNode[2];
3169 pNode[2]->mNext = mQuestionList;
3170 mQuestionList = pNode[0];
3171
3172 for (Index = 0; Index < 3; Index++) {
3173 if (VarIdStr[Index] != NULL) {
3174 delete[] VarIdStr[Index];
3175 VarIdStr[Index] = NULL;
3176 }
3177 }
3178
3179 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3180 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3181 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3182
3183 return;
3184
3185 Err:
3186 for (Index = 0; Index < 3; Index++) {
3187 if (pNode[Index] != NULL) {
3188 delete pNode[Index];
3189 }
3190
3191 if (VarIdStr[Index] != NULL) {
3192 delete[] VarIdStr[Index];
3193 VarIdStr[Index] = NULL;
3194 }
3195 }
3196 }
3197
3198 VOID
3199 CVfrQuestionDB::RegisterRefQuestion (
3200 IN CHAR8 *Name,
3201 IN CHAR8 *BaseVarId,
3202 IN OUT EFI_QUESTION_ID &QuestionId
3203 )
3204 {
3205 SVfrQuestionNode *pNode[4] = {NULL, };
3206 UINT32 Len;
3207 CHAR8 *VarIdStr[4] = {NULL, };
3208 CHAR8 Index;
3209
3210 if (BaseVarId == NULL && Name == NULL) {
3211 return;
3212 }
3213
3214 if (BaseVarId != NULL) {
3215 Len = strlen (BaseVarId);
3216
3217 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3218 if (VarIdStr[0] != NULL) {
3219 strcpy (VarIdStr[0], BaseVarId);
3220 strcat (VarIdStr[0], ".QuestionId");
3221 }
3222 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3223 if (VarIdStr[1] != NULL) {
3224 strcpy (VarIdStr[1], BaseVarId);
3225 strcat (VarIdStr[1], ".FormId");
3226 }
3227 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3228 if (VarIdStr[2] != NULL) {
3229 strcpy (VarIdStr[2], BaseVarId);
3230 strcat (VarIdStr[2], ".FormSetGuid");
3231 }
3232 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3233 if (VarIdStr[3] != NULL) {
3234 strcpy (VarIdStr[3], BaseVarId);
3235 strcat (VarIdStr[3], ".DevicePath");
3236 }
3237 } else {
3238 Len = strlen (Name);
3239
3240 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
3241 if (VarIdStr[0] != NULL) {
3242 strcpy (VarIdStr[0], Name);
3243 strcat (VarIdStr[0], ".QuestionId");
3244 }
3245 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
3246 if (VarIdStr[1] != NULL) {
3247 strcpy (VarIdStr[1], Name);
3248 strcat (VarIdStr[1], ".FormId");
3249 }
3250 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
3251 if (VarIdStr[2] != NULL) {
3252 strcpy (VarIdStr[2], Name);
3253 strcat (VarIdStr[2], ".FormSetGuid");
3254 }
3255 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
3256 if (VarIdStr[3] != NULL) {
3257 strcpy (VarIdStr[3], Name);
3258 strcat (VarIdStr[3], ".DevicePath");
3259 }
3260 }
3261
3262 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
3263 goto Err;
3264 }
3265 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
3266 goto Err;
3267 }
3268 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
3269 goto Err;
3270 }
3271 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
3272 goto Err;
3273 }
3274
3275 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3276 QuestionId = GetFreeQuestionId ();
3277 } else {
3278 if (ChekQuestionIdFree (QuestionId) == FALSE) {
3279 goto Err;
3280 }
3281 MarkQuestionIdUsed (QuestionId);
3282 }
3283
3284 pNode[0]->mQuestionId = QuestionId;
3285 pNode[1]->mQuestionId = QuestionId;
3286 pNode[2]->mQuestionId = QuestionId;
3287 pNode[3]->mQuestionId = QuestionId;
3288 pNode[0]->mQtype = QUESTION_REF;
3289 pNode[1]->mQtype = QUESTION_REF;
3290 pNode[2]->mQtype = QUESTION_REF;
3291 pNode[3]->mQtype = QUESTION_REF;
3292 pNode[0]->mNext = pNode[1];
3293 pNode[1]->mNext = pNode[2];
3294 pNode[2]->mNext = pNode[3];
3295 pNode[3]->mNext = mQuestionList;
3296 mQuestionList = pNode[0];
3297
3298 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3299 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3300 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3301 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
3302
3303 return;
3304
3305 Err:
3306 for (Index = 0; Index < 4; Index++) {
3307 if (pNode[Index] != NULL) {
3308 delete pNode[Index];
3309 }
3310
3311 if (VarIdStr[Index] != NULL) {
3312 delete VarIdStr[Index];
3313 }
3314 }
3315 }
3316
3317 EFI_VFR_RETURN_CODE
3318 CVfrQuestionDB::UpdateQuestionId (
3319 IN EFI_QUESTION_ID QId,
3320 IN EFI_QUESTION_ID NewQId
3321 )
3322 {
3323 SVfrQuestionNode *pNode = NULL;
3324
3325 if (QId == NewQId) {
3326 // don't update
3327 return VFR_RETURN_SUCCESS;
3328 }
3329
3330 if (ChekQuestionIdFree (NewQId) == FALSE) {
3331 return VFR_RETURN_REDEFINED;
3332 }
3333
3334 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3335 if (pNode->mQuestionId == QId) {
3336 break;
3337 }
3338 }
3339
3340 if (pNode == NULL) {
3341 return VFR_RETURN_UNDEFINED;
3342 }
3343
3344 MarkQuestionIdUnused (QId);
3345 pNode->mQuestionId = NewQId;
3346 MarkQuestionIdUsed (NewQId);
3347
3348 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
3349
3350 return VFR_RETURN_SUCCESS;
3351 }
3352
3353 VOID
3354 CVfrQuestionDB::GetQuestionId (
3355 IN CHAR8 *Name,
3356 IN CHAR8 *VarIdStr,
3357 OUT EFI_QUESTION_ID &QuestionId,
3358 OUT UINT32 &BitMask,
3359 OUT EFI_QUESION_TYPE *QType
3360 )
3361 {
3362 SVfrQuestionNode *pNode;
3363
3364 QuestionId = EFI_QUESTION_ID_INVALID;
3365 BitMask = 0x00000000;
3366 if (QType != NULL) {
3367 *QType = QUESTION_NORMAL;
3368 }
3369
3370 if ((Name == NULL) && (VarIdStr == NULL)) {
3371 return ;
3372 }
3373
3374 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3375 if (Name != NULL) {
3376 if (strcmp (pNode->mName, Name) != 0) {
3377 continue;
3378 }
3379 }
3380
3381 if (VarIdStr != NULL) {
3382 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
3383 continue;
3384 }
3385 }
3386
3387 QuestionId = pNode->mQuestionId;
3388 BitMask = pNode->mBitMask;
3389 if (QType != NULL) {
3390 *QType = pNode->mQtype;
3391 }
3392 break;
3393 }
3394
3395 return ;
3396 }
3397
3398 EFI_VFR_RETURN_CODE
3399 CVfrQuestionDB::FindQuestion (
3400 IN EFI_QUESTION_ID QuestionId
3401 )
3402 {
3403 SVfrQuestionNode *pNode;
3404
3405 if (QuestionId == EFI_QUESTION_ID_INVALID) {
3406 return VFR_RETURN_INVALID_PARAMETER;
3407 }
3408
3409 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3410 if (pNode->mQuestionId == QuestionId) {
3411 return VFR_RETURN_SUCCESS;
3412 }
3413 }
3414
3415 return VFR_RETURN_UNDEFINED;
3416 }
3417
3418 EFI_VFR_RETURN_CODE
3419 CVfrQuestionDB::FindQuestion (
3420 IN CHAR8 *Name
3421 )
3422 {
3423 SVfrQuestionNode *pNode;
3424
3425 if (Name == NULL) {
3426 return VFR_RETURN_FATAL_ERROR;
3427 }
3428
3429 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
3430 if (strcmp (pNode->mName, Name) == 0) {
3431 return VFR_RETURN_SUCCESS;
3432 }
3433 }
3434
3435 return VFR_RETURN_UNDEFINED;
3436 }
3437
3438 CVfrStringDB::CVfrStringDB ()
3439 {
3440 mStringFileName = NULL;
3441 }
3442
3443 CVfrStringDB::~CVfrStringDB ()
3444 {
3445 if (mStringFileName != NULL) {
3446 delete[] mStringFileName;
3447 }
3448 mStringFileName = NULL;
3449 }
3450
3451
3452 VOID
3453 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
3454 {
3455 UINT32 FileLen = 0;
3456
3457 if (StringFileName == NULL) {
3458 return;
3459 }
3460
3461 if (mStringFileName != NULL) {
3462 delete[] mStringFileName;
3463 }
3464
3465 FileLen = strlen (StringFileName) + 1;
3466 mStringFileName = new CHAR8[FileLen];
3467 if (mStringFileName == NULL) {
3468 return;
3469 }
3470
3471 strcpy (mStringFileName, StringFileName);
3472 mStringFileName[FileLen - 1] = '\0';
3473 }
3474
3475
3476 /**
3477 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
3478 from a set of supported languages.
3479
3480 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
3481 contains a set of language codes.
3482 @param[in] Language A variable that contains pointers to Null-terminated
3483 ASCII strings that contain one language codes.
3484
3485 @retval FALSE The best matching language could not be found in SupportedLanguages.
3486 @retval TRUE The best matching language could be found in SupportedLanguages.
3487
3488 **/
3489 BOOLEAN
3490 CVfrStringDB::GetBestLanguage (
3491 IN CONST CHAR8 *SupportedLanguages,
3492 IN CHAR8 *Language
3493 )
3494 {
3495 UINTN CompareLength;
3496 UINTN LanguageLength;
3497 CONST CHAR8 *Supported;
3498
3499 if (SupportedLanguages == NULL || Language == NULL){
3500 return FALSE;
3501 }
3502
3503 //
3504 // Determine the length of the first RFC 4646 language code in Language
3505 //
3506 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
3507
3508 //
3509 // Trim back the length of Language used until it is empty
3510 //
3511 while (LanguageLength > 0) {
3512 //
3513 // Loop through all language codes in SupportedLanguages
3514 //
3515 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
3516 //
3517 // Skip ';' characters in Supported
3518 //
3519 for (; *Supported != '\0' && *Supported == ';'; Supported++);
3520 //
3521 // Determine the length of the next language code in Supported
3522 //
3523 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
3524 //
3525 // If Language is longer than the Supported, then skip to the next language
3526 //
3527 if (LanguageLength > CompareLength) {
3528 continue;
3529 }
3530
3531 //
3532 // See if the first LanguageLength characters in Supported match Language
3533 //
3534 if (strncmp (Supported, Language, LanguageLength) == 0) {
3535 return TRUE;
3536 }
3537 }
3538
3539 //
3540 // Trim Language from the right to the next '-' character
3541 //
3542 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
3543 }
3544
3545 //
3546 // No matches were found
3547 //
3548 return FALSE;
3549 }
3550
3551
3552 CHAR8 *
3553 CVfrStringDB::GetVarStoreNameFormStringId (
3554 IN EFI_STRING_ID StringId
3555 )
3556 {
3557 FILE *pInFile = NULL;
3558 UINT32 NameOffset;
3559 UINT32 Length;
3560 UINT8 *StringPtr;
3561 CHAR8 *StringName;
3562 CHAR16 *UnicodeString;
3563 CHAR8 *VarStoreName = NULL;
3564 CHAR8 *DestTmp;
3565 UINT8 *Current;
3566 EFI_STATUS Status;
3567 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
3568 UINT8 BlockType;
3569 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
3570
3571 if (mStringFileName == NULL) {
3572 return NULL;
3573 }
3574
3575 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
3576 return NULL;
3577 }
3578
3579 //
3580 // Get file length.
3581 //
3582 fseek (pInFile, 0, SEEK_END);
3583 Length = ftell (pInFile);
3584 fseek (pInFile, 0, SEEK_SET);
3585
3586 //
3587 // Get file data.
3588 //
3589 StringPtr = new UINT8[Length];
3590 if (StringPtr == NULL) {
3591 fclose (pInFile);
3592 return NULL;
3593 }
3594 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
3595 fclose (pInFile);
3596
3597 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3598 //
3599 // Check the String package.
3600 //
3601 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
3602 delete[] StringPtr;
3603 return NULL;
3604 }
3605
3606 //
3607 // Search the language, get best language base on RFC 4647 matching algorithm.
3608 //
3609 Current = StringPtr;
3610 while (!GetBestLanguage ("en", PkgHeader->Language)) {
3611 Current += PkgHeader->Header.Length;
3612 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
3613 //
3614 // If can't find string package base on language, just return the first string package.
3615 //
3616 if (Current - StringPtr >= Length) {
3617 Current = StringPtr;
3618 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
3619 break;
3620 }
3621 }
3622
3623 Current += PkgHeader->HdrSize;
3624 //
3625 // Find the string block according the stringId.
3626 //
3627 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
3628 if (Status != EFI_SUCCESS) {
3629 delete[] StringPtr;
3630 return NULL;
3631 }
3632
3633 //
3634 // Get varstore name according the string type.
3635 //
3636 switch (BlockType) {
3637 case EFI_HII_SIBT_STRING_SCSU:
3638 case EFI_HII_SIBT_STRING_SCSU_FONT:
3639 case EFI_HII_SIBT_STRINGS_SCSU:
3640 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3641 StringName = (CHAR8*)(Current + NameOffset);
3642 VarStoreName = new CHAR8[strlen(StringName) + 1];
3643 strcpy (VarStoreName, StringName);
3644 break;
3645 case EFI_HII_SIBT_STRING_UCS2:
3646 case EFI_HII_SIBT_STRING_UCS2_FONT:
3647 case EFI_HII_SIBT_STRINGS_UCS2:
3648 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3649 UnicodeString = (CHAR16*)(Current + NameOffset);
3650 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
3651 DestTmp = new CHAR8[Length / 2 + 1];
3652 VarStoreName = DestTmp;
3653 while (*UnicodeString != '\0') {
3654 *(DestTmp++) = (CHAR8) *(UnicodeString++);
3655 }
3656 *DestTmp = '\0';
3657 break;
3658 default:
3659 break;
3660 }
3661
3662 delete[] StringPtr;
3663
3664 return VarStoreName;
3665 }
3666
3667 EFI_STATUS
3668 CVfrStringDB::FindStringBlock (
3669 IN UINT8 *StringData,
3670 IN EFI_STRING_ID StringId,
3671 OUT UINT32 *StringTextOffset,
3672 OUT UINT8 *BlockType
3673 )
3674 {
3675 UINT8 *BlockHdr;
3676 EFI_STRING_ID CurrentStringId;
3677 UINT32 BlockSize;
3678 UINT32 Index;
3679 UINT8 *StringTextPtr;
3680 UINT32 Offset;
3681 UINT16 StringCount;
3682 UINT16 SkipCount;
3683 UINT8 Length8;
3684 EFI_HII_SIBT_EXT2_BLOCK Ext2;
3685 UINT32 Length32;
3686 UINT32 StringSize;
3687
3688 CurrentStringId = 1;
3689
3690 //
3691 // Parse the string blocks to get the string text and font.
3692 //
3693 BlockHdr = StringData;
3694 BlockSize = 0;
3695 Offset = 0;
3696 while (*BlockHdr != EFI_HII_SIBT_END) {
3697 switch (*BlockHdr) {
3698 case EFI_HII_SIBT_STRING_SCSU:
3699 Offset = sizeof (EFI_HII_STRING_BLOCK);
3700 StringTextPtr = BlockHdr + Offset;
3701 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3702 CurrentStringId++;
3703 break;
3704
3705 case EFI_HII_SIBT_STRING_SCSU_FONT:
3706 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
3707 StringTextPtr = BlockHdr + Offset;
3708 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
3709 CurrentStringId++;
3710 break;
3711
3712 case EFI_HII_SIBT_STRINGS_SCSU:
3713 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3714 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
3715 BlockSize += StringTextPtr - BlockHdr;
3716
3717 for (Index = 0; Index < StringCount; Index++) {
3718 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3719 if (CurrentStringId == StringId) {
3720 *BlockType = *BlockHdr;
3721 *StringTextOffset = StringTextPtr - StringData;
3722 return EFI_SUCCESS;
3723 }
3724 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3725 CurrentStringId++;
3726 }
3727 break;
3728
3729 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
3730 memcpy (
3731 &StringCount,
3732 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3733 sizeof (UINT16)
3734 );
3735 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
3736 BlockSize += StringTextPtr - BlockHdr;
3737
3738 for (Index = 0; Index < StringCount; Index++) {
3739 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
3740 if (CurrentStringId == StringId) {
3741 *BlockType = *BlockHdr;
3742 *StringTextOffset = StringTextPtr - StringData;
3743 return EFI_SUCCESS;
3744 }
3745 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
3746 CurrentStringId++;
3747 }
3748 break;
3749
3750 case EFI_HII_SIBT_STRING_UCS2:
3751 Offset = sizeof (EFI_HII_STRING_BLOCK);
3752 StringTextPtr = BlockHdr + Offset;
3753 //
3754 // Use StringSize to store the size of the specified string, including the NULL
3755 // terminator.
3756 //
3757 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3758 BlockSize += Offset + StringSize;
3759 CurrentStringId++;
3760 break;
3761
3762 case EFI_HII_SIBT_STRING_UCS2_FONT:
3763 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3764 StringTextPtr = BlockHdr + Offset;
3765 //
3766 // Use StrSize to store the size of the specified string, including the NULL
3767 // terminator.
3768 //
3769 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3770 BlockSize += Offset + StringSize;
3771 CurrentStringId++;
3772 break;
3773
3774 case EFI_HII_SIBT_STRINGS_UCS2:
3775 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
3776 StringTextPtr = BlockHdr + Offset;
3777 BlockSize += Offset;
3778 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3779 for (Index = 0; Index < StringCount; Index++) {
3780 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3781 BlockSize += StringSize;
3782 if (CurrentStringId == StringId) {
3783 *BlockType = *BlockHdr;
3784 *StringTextOffset = StringTextPtr - StringData;
3785 return EFI_SUCCESS;
3786 }
3787 StringTextPtr = StringTextPtr + StringSize;
3788 CurrentStringId++;
3789 }
3790 break;
3791
3792 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
3793 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
3794 StringTextPtr = BlockHdr + Offset;
3795 BlockSize += Offset;
3796 memcpy (
3797 &StringCount,
3798 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3799 sizeof (UINT16)
3800 );
3801 for (Index = 0; Index < StringCount; Index++) {
3802 StringSize = GetUnicodeStringTextSize (StringTextPtr);
3803 BlockSize += StringSize;
3804 if (CurrentStringId == StringId) {
3805 *BlockType = *BlockHdr;
3806 *StringTextOffset = StringTextPtr - StringData;
3807 return EFI_SUCCESS;
3808 }
3809 StringTextPtr = StringTextPtr + StringSize;
3810 CurrentStringId++;
3811 }
3812 break;
3813
3814 case EFI_HII_SIBT_DUPLICATE:
3815 if (CurrentStringId == StringId) {
3816 //
3817 // Incoming StringId is an id of a duplicate string block.
3818 // Update the StringId to be the previous string block.
3819 // Go back to the header of string block to search.
3820 //
3821 memcpy (
3822 &StringId,
3823 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
3824 sizeof (EFI_STRING_ID)
3825 );
3826 CurrentStringId = 1;
3827 BlockSize = 0;
3828 } else {
3829 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
3830 CurrentStringId++;
3831 }
3832 break;
3833
3834 case EFI_HII_SIBT_SKIP1:
3835 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
3836 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3837 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
3838 break;
3839
3840 case EFI_HII_SIBT_SKIP2:
3841 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
3842 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
3843 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
3844 break;
3845
3846 case EFI_HII_SIBT_EXT1:
3847 memcpy (
3848 &Length8,
3849 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3850 sizeof (UINT8)
3851 );
3852 BlockSize += Length8;
3853 break;
3854
3855 case EFI_HII_SIBT_EXT2:
3856 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
3857 BlockSize += Ext2.Length;
3858 break;
3859
3860 case EFI_HII_SIBT_EXT4:
3861 memcpy (
3862 &Length32,
3863 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
3864 sizeof (UINT32)
3865 );
3866
3867 BlockSize += Length32;
3868 break;
3869
3870 default:
3871 break;
3872 }
3873
3874 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
3875 *StringTextOffset = BlockHdr - StringData + Offset;
3876 *BlockType = *BlockHdr;
3877
3878 if (StringId == CurrentStringId - 1) {
3879 //
3880 // if only one skip item, return EFI_NOT_FOUND.
3881 //
3882 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
3883 return EFI_NOT_FOUND;
3884 } else {
3885 return EFI_SUCCESS;
3886 }
3887 }
3888
3889 if (StringId < CurrentStringId - 1) {
3890 return EFI_NOT_FOUND;
3891 }
3892 }
3893 BlockHdr = StringData + BlockSize;
3894 }
3895
3896 return EFI_NOT_FOUND;
3897 }
3898
3899 UINT32
3900 CVfrStringDB::GetUnicodeStringTextSize (
3901 IN UINT8 *StringSrc
3902 )
3903 {
3904 UINT32 StringSize;
3905 CHAR16 *StringPtr;
3906
3907 StringSize = sizeof (CHAR16);
3908 StringPtr = (UINT16*)StringSrc;
3909 while (*StringPtr++ != L'\0') {
3910 StringSize += sizeof (CHAR16);
3911 }
3912
3913 return StringSize;
3914 }
3915
3916 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
3917 CVfrDefaultStore gCVfrDefaultStore;
3918 CVfrDataStorage gCVfrDataStorage;
3919
3920