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