VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp

Last change on this file was 99404, checked in by vboxsync, 2 years ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette