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