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