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