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