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