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