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