]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
Fix VfrCompiler bug to create varstore name by varstore name field not structure...
[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
5Copyright (c) 2004 - 2008, Intel Corporation \r
6All rights reserved. This program and the accompanying materials \r
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
23 IN FILE *pFile,\r
24 IN UINT32 LineBytes,\r
25 IN CHAR8 *LineHeader,\r
26 IN CHAR8 *BlkBuf,\r
27 IN UINT32 BlkSize\r
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
46 IN FILE *pFile,\r
47 IN UINT32 LineBytes,\r
48 IN CHAR8 *LineHeader,\r
49 IN CHAR8 *BlkBuf,\r
50 IN UINT32 BlkSize\r
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
290 if ((pItem = new SConfigItem (Name, Id, Type, Offset, Width, Value)) == NULL) {\r
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
458 CHAR8 *mTypeName;\r
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
625 return VFR_RETURN_SUCCESS;\r
626 case ']':\r
627 return VFR_RETURN_DATA_STRING_ERROR;\r
628 }\r
629\r
630 return VFR_RETURN_SUCCESS;\r
631}\r
632\r
633EFI_VFR_RETURN_CODE\r
634CVfrVarDataTypeDB::GetTypeField (\r
635 IN CHAR8 *FName,\r
636 IN SVfrDataType *Type,\r
637 OUT SVfrDataField *&Field\r
638 )\r
639{\r
640 SVfrDataField *pField = NULL;\r
641\r
642 if ((FName == NULL) && (Type == NULL)) {\r
643 return VFR_RETURN_FATAL_ERROR;\r
644 }\r
645\r
646 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
647 if (strcmp (pField->mFieldName, FName) == 0) {\r
648 Field = pField;\r
649 return VFR_RETURN_SUCCESS;\r
650 }\r
651 }\r
652\r
653 return VFR_RETURN_UNDEFINED;\r
654}\r
655\r
656EFI_VFR_RETURN_CODE\r
657CVfrVarDataTypeDB::GetFieldOffset (\r
658 IN SVfrDataField *Field,\r
659 IN UINT32 ArrayIdx,\r
660 OUT UINT32 &Offset\r
661 )\r
662{\r
663 if (Field == NULL) {\r
664 return VFR_RETURN_FATAL_ERROR;\r
665 }\r
666 \r
667 //\r
668 // Framework Vfr file Array Index is from 1.\r
669 // But Uefi Vfr file Array Index is from 0.\r
670 //\r
671 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {\r
672 if (ArrayIdx == 0) {\r
673 return VFR_RETURN_ERROR_ARRARY_NUM;\r
674 }\r
675 ArrayIdx = ArrayIdx - 1;\r
676 }\r
677\r
678 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
679 return VFR_RETURN_ERROR_ARRARY_NUM;\r
680 }\r
681 \r
682 //\r
683 // Be compatible with the current usage\r
684 // If ArraryIdx is not specified, the first one is used.\r
685 //\r
686 // if ArrayNum is larger than zero, ArraryIdx must be specified.\r
687 //\r
688 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {\r
689 // return VFR_RETURN_ERROR_ARRARY_NUM;\r
690 // }\r
691 //\r
692\r
693 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
694 return VFR_RETURN_SUCCESS;\r
695}\r
696\r
697UINT8\r
698CVfrVarDataTypeDB::GetFieldWidth (\r
699 IN SVfrDataField *Field\r
700 )\r
701{\r
702 if (Field == NULL) {\r
703 return 0;\r
704 }\r
705\r
706 return Field->mFieldType->mType;\r
707}\r
708\r
709UINT32\r
710CVfrVarDataTypeDB::GetFieldSize (\r
711 IN SVfrDataField *Field,\r
712 IN UINT32 ArrayIdx\r
713 )\r
714{\r
715 if (Field == NULL) {\r
716 return VFR_RETURN_FATAL_ERROR;\r
717 }\r
718\r
719 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
720 return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
721 } else {\r
722 return Field->mFieldType->mTotalSize;\r
723 }\r
724}\r
725\r
726VOID\r
727CVfrVarDataTypeDB::InternalTypesListInit (\r
728 VOID\r
729 )\r
730{\r
731 SVfrDataType *New = NULL;\r
732 UINT32 Index;\r
733\r
734 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
735 New = new SVfrDataType;\r
736 if (New != NULL) {\r
737 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
738 New->mType = gInternalTypesTable[Index].mType;\r
739 New->mAlign = gInternalTypesTable[Index].mAlign;\r
740 New->mTotalSize = gInternalTypesTable[Index].mSize;\r
741 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {\r
742 SVfrDataField *pYearField = new SVfrDataField;\r
743 SVfrDataField *pMonthField = new SVfrDataField;\r
744 SVfrDataField *pDayField = new SVfrDataField;\r
745\r
746 strcpy (pYearField->mFieldName, "Year");\r
747 GetDataType ("UINT8", &pYearField->mFieldType);\r
748 pYearField->mOffset = 0;\r
749 pYearField->mNext = pMonthField;\r
750 pYearField->mArrayNum = 0;\r
751\r
752 strcpy (pMonthField->mFieldName, "Month");\r
753 GetDataType ("UINT8", &pMonthField->mFieldType);\r
754 pMonthField->mOffset = 1;\r
755 pMonthField->mNext = pDayField;\r
756 pMonthField->mArrayNum = 0;\r
757\r
758 strcpy (pDayField->mFieldName, "Day");\r
759 GetDataType ("UINT8", &pDayField->mFieldType);\r
760 pDayField->mOffset = 2;\r
761 pDayField->mNext = NULL;\r
762 pDayField->mArrayNum = 0;\r
763\r
764 New->mMembers = pYearField;\r
765 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
766 SVfrDataField *pHoursField = new SVfrDataField;\r
767 SVfrDataField *pMinutesField = new SVfrDataField;\r
768 SVfrDataField *pSecondsField = new SVfrDataField;\r
769\r
770 strcpy (pHoursField->mFieldName, "Hours");\r
771 GetDataType ("UINT8", &pHoursField->mFieldType);\r
772 pHoursField->mOffset = 0;\r
773 pHoursField->mNext = pMinutesField;\r
774 pHoursField->mArrayNum = 0;\r
775\r
776 strcpy (pMinutesField->mFieldName, "Minutes");\r
777 GetDataType ("UINT8", &pMinutesField->mFieldType);\r
778 pMinutesField->mOffset = 1;\r
779 pMinutesField->mNext = pSecondsField;\r
780 pMinutesField->mArrayNum = 0;\r
781\r
782 strcpy (pSecondsField->mFieldName, "Seconds");\r
783 GetDataType ("UINT8", &pSecondsField->mFieldType);\r
784 pSecondsField->mOffset = 2;\r
785 pSecondsField->mNext = NULL;\r
786 pSecondsField->mArrayNum = 0;\r
787\r
788 New->mMembers = pHoursField;\r
789 } else {\r
790 New->mMembers = NULL;\r
791 }\r
792 New->mNext = NULL;\r
793 RegisterNewType (New);\r
794 New = NULL;\r
795 }\r
796 }\r
797}\r
798\r
799CVfrVarDataTypeDB::CVfrVarDataTypeDB (\r
800 VOID\r
801 )\r
802{\r
803 mDataTypeList = NULL;\r
804 mNewDataType = NULL;\r
805 mCurrDataField = NULL;\r
806 mPackAlign = DEFAULT_PACK_ALIGN;\r
807 mPackStack = NULL;\r
808 mFirstNewDataTypeName = NULL;\r
809\r
810 InternalTypesListInit ();\r
811}\r
812\r
813CVfrVarDataTypeDB::~CVfrVarDataTypeDB (\r
814 VOID\r
815 )\r
816{\r
817 SVfrDataType *pType;\r
818 SVfrDataField *pField;\r
819 SVfrPackStackNode *pPack;\r
820\r
821 if (mNewDataType != NULL) {\r
822 delete mNewDataType;\r
823 }\r
824\r
825 while (mDataTypeList != NULL) {\r
826 pType = mDataTypeList;\r
827 mDataTypeList = mDataTypeList->mNext;\r
828 while(pType->mMembers != NULL) {\r
829 pField = pType->mMembers;\r
830 pType->mMembers = pType->mMembers->mNext;\r
831 delete pField;\r
832 }\r
833 delete pType;\r
834 }\r
835\r
836 while (mPackStack != NULL) {\r
837 pPack = mPackStack;\r
838 mPackStack = mPackStack->mNext;\r
839 delete pPack;\r
840 }\r
841}\r
842\r
843EFI_VFR_RETURN_CODE\r
844CVfrVarDataTypeDB::Pack (\r
845 IN UINT32 LineNum,\r
846 IN UINT8 Action,\r
847 IN CHAR8 *Identifier,\r
848 IN UINT32 Number\r
849 )\r
850{\r
851 UINT32 PackAlign;\r
852 CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
853\r
854 if (Action & VFR_PACK_SHOW) {\r
855 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
856 gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);\r
857 }\r
858\r
859 if (Action & VFR_PACK_PUSH) {\r
860 SVfrPackStackNode *pNew = NULL;\r
861\r
862 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {\r
863 return VFR_RETURN_FATAL_ERROR;\r
864 }\r
865 pNew->mNext = mPackStack;\r
866 mPackStack = pNew;\r
867 }\r
868\r
869 if (Action & VFR_PACK_POP) {\r
870 SVfrPackStackNode *pNode = NULL;\r
871\r
872 if (mPackStack == NULL) {\r
873 gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "#pragma pack(pop...) : more pops than pushes");\r
874 }\r
875\r
876 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
877 if (pNode->Match (Identifier) == TRUE) {\r
878 mPackAlign = pNode->mNumber;\r
879 mPackStack = pNode->mNext;\r
880 }\r
881 }\r
882 }\r
883\r
884 if (Action & VFR_PACK_ASSIGN) {\r
885 PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
886 if ((PackAlign == 0) || (PackAlign > 16)) {\r
887 gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
888 } else {\r
889 mPackAlign = PackAlign;\r
890 }\r
891 }\r
892\r
893 return VFR_RETURN_SUCCESS;\r
894}\r
895\r
896VOID\r
897CVfrVarDataTypeDB::DeclareDataTypeBegin (\r
898 VOID\r
899 )\r
900{\r
901 SVfrDataType *pNewType = NULL;\r
902\r
903 pNewType = new SVfrDataType;\r
904 pNewType->mTypeName[0] = '\0';\r
905 pNewType->mType = EFI_IFR_TYPE_OTHER;\r
906 pNewType->mAlign = DEFAULT_ALIGN;\r
907 pNewType->mTotalSize = 0;\r
908 pNewType->mMembers = NULL;\r
909 pNewType->mNext = NULL;\r
910\r
911 mNewDataType = pNewType;\r
912}\r
913\r
914EFI_VFR_RETURN_CODE\r
915CVfrVarDataTypeDB::SetNewTypeName (\r
916 IN CHAR8 *TypeName\r
917 )\r
918{\r
919 SVfrDataType *pType;\r
920\r
921 if (mNewDataType == NULL) {\r
922 return VFR_RETURN_ERROR_SKIPED;\r
923 }\r
924 if (TypeName == NULL) {\r
925 return VFR_RETURN_FATAL_ERROR;\r
926 }\r
927 if (strlen(TypeName) >= MAX_NAME_LEN) {\r
928 return VFR_RETURN_INVALID_PARAMETER;\r
929 }\r
930\r
931 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
932 if (strcmp(pType->mTypeName, TypeName) == 0) {\r
933 return VFR_RETURN_REDEFINED;\r
934 }\r
935 }\r
936\r
937 strcpy(mNewDataType->mTypeName, TypeName);\r
938 return VFR_RETURN_SUCCESS;\r
939}\r
940\r
941EFI_VFR_RETURN_CODE\r
942CVfrVarDataTypeDB::DataTypeAddField (\r
943 IN CHAR8 *FieldName,\r
944 IN CHAR8 *TypeName,\r
945 IN UINT32 ArrayNum\r
946 )\r
947{\r
948 SVfrDataField *pNewField = NULL;\r
949 SVfrDataType *pFieldType = NULL;\r
950 SVfrDataField *pTmp;\r
951 UINT32 Align;\r
952\r
953 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
954\r
955 if (strlen (FieldName) >= MAX_NAME_LEN) {\r
956 return VFR_RETURN_INVALID_PARAMETER;\r
957 }\r
958\r
959 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
960 if (strcmp (pTmp->mFieldName, FieldName) == 0) {\r
961 return VFR_RETURN_REDEFINED;\r
962 }\r
963 }\r
964\r
965 Align = MIN (mPackAlign, pFieldType->mAlign);\r
966\r
967 if ((pNewField = new SVfrDataField) == NULL) {\r
968 return VFR_RETURN_OUT_FOR_RESOURCES;\r
969 }\r
970 strcpy (pNewField->mFieldName, FieldName);\r
971 pNewField->mFieldType = pFieldType;\r
972 pNewField->mArrayNum = ArrayNum;\r
973 if ((mNewDataType->mTotalSize % Align) == 0) {\r
974 pNewField->mOffset = mNewDataType->mTotalSize;\r
975 } else {\r
976 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
977 }\r
978 if (mNewDataType->mMembers == NULL) {\r
979 mNewDataType->mMembers = pNewField;\r
980 pNewField->mNext = NULL;\r
981 } else {\r
982 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
983 ;\r
984 pTmp->mNext = pNewField;\r
985 pNewField->mNext = NULL;\r
986 }\r
987\r
988 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
989 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
990\r
991 return VFR_RETURN_SUCCESS;\r
992}\r
993\r
994VOID\r
995CVfrVarDataTypeDB::DeclareDataTypeEnd (\r
996 VOID\r
997 )\r
998{\r
999 if (mNewDataType->mTypeName[0] == '\0') {\r
1000 return;\r
1001 }\r
1002\r
1003 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {\r
1004 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);\r
1005 }\r
1006\r
1007 RegisterNewType (mNewDataType);\r
1008 if (mFirstNewDataTypeName == NULL) {\r
1009 mFirstNewDataTypeName = mNewDataType->mTypeName;\r
1010 }\r
1011\r
1012 mNewDataType = NULL;\r
1013}\r
1014\r
1015EFI_VFR_RETURN_CODE\r
1016CVfrVarDataTypeDB::GetDataType (\r
1017 IN CHAR8 *TypeName,\r
1018 OUT SVfrDataType **DataType\r
1019 )\r
1020{\r
1021 SVfrDataType *pDataType = NULL;\r
1022\r
1023 if (TypeName == NULL) {\r
1024 return VFR_RETURN_ERROR_SKIPED;\r
1025 }\r
1026\r
1027 if (DataType == NULL) {\r
1028 return VFR_RETURN_FATAL_ERROR;\r
1029 }\r
1030\r
1031 *DataType = NULL;\r
1032\r
1033 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1034 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1035 *DataType = pDataType;\r
1036 return VFR_RETURN_SUCCESS;\r
1037 }\r
1038 }\r
1039\r
1040 return VFR_RETURN_UNDEFINED;\r
1041}\r
1042\r
1043EFI_VFR_RETURN_CODE\r
1044CVfrVarDataTypeDB::GetDataTypeSize (\r
1045 IN UINT8 DataType,\r
1046 OUT UINT32 *Size\r
1047 )\r
1048{\r
1049 SVfrDataType *pDataType = NULL;\r
1050\r
1051 if (Size == NULL) {\r
1052 return VFR_RETURN_FATAL_ERROR;\r
1053 }\r
1054\r
1055 *Size = 0;\r
1056 DataType = DataType & 0x0F;\r
1057\r
1058 //\r
1059 // For user defined data type, the size can't be got by this function.\r
1060 //\r
1061 if (DataType == EFI_IFR_TYPE_OTHER) {\r
1062 return VFR_RETURN_SUCCESS;\r
1063 }\r
1064\r
1065 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1066 if (DataType == pDataType->mType) {\r
1067 *Size = pDataType->mTotalSize;\r
1068 return VFR_RETURN_SUCCESS;\r
1069 }\r
1070 }\r
1071\r
1072 return VFR_RETURN_UNDEFINED;\r
1073}\r
1074\r
1075EFI_VFR_RETURN_CODE\r
1076CVfrVarDataTypeDB::GetDataTypeSize (\r
1077 IN CHAR8 *TypeName,\r
1078 OUT UINT32 *Size\r
1079 )\r
1080{\r
1081 SVfrDataType *pDataType = NULL;\r
1082\r
1083 if (Size == NULL) {\r
1084 return VFR_RETURN_FATAL_ERROR;\r
1085 }\r
1086\r
1087 *Size = 0;\r
1088\r
1089 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1090 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1091 *Size = pDataType->mTotalSize;\r
1092 return VFR_RETURN_SUCCESS;\r
1093 }\r
1094 }\r
1095\r
1096 return VFR_RETURN_UNDEFINED;\r
1097}\r
1098\r
1099EFI_VFR_RETURN_CODE\r
1100CVfrVarDataTypeDB::GetDataFieldInfo (\r
1101 IN CHAR8 *VarStr,\r
1102 OUT UINT16 &Offset,\r
1103 OUT UINT8 &Type,\r
1104 OUT UINT32 &Size\r
1105 )\r
1106{\r
1107 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
1108 UINT32 ArrayIdx, Tmp;\r
1109 SVfrDataType *pType = NULL;\r
1110 SVfrDataField *pField = NULL;\r
1111\r
1112 Offset = 0;\r
1113 Type = EFI_IFR_TYPE_OTHER;\r
1114 Size = 0;\r
1115\r
1116 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
1117 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
1118\r
1119 //\r
1120 // if it is not struct data type\r
1121 //\r
1122 Type = pType->mType;\r
1123 Size = pType->mTotalSize;\r
1124\r
1125 while (*VarStr != '\0') {\r
1126 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
1127 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
1128 pType = pField->mFieldType;\r
1129 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
1130 Offset += Tmp;\r
1131 Type = GetFieldWidth (pField);\r
1132 Size = GetFieldSize (pField, ArrayIdx);\r
1133 }\r
1134 return VFR_RETURN_SUCCESS;\r
1135}\r
1136\r
1137EFI_VFR_RETURN_CODE\r
1138CVfrVarDataTypeDB::GetUserDefinedTypeNameList (\r
1139 OUT CHAR8 ***NameList,\r
1140 OUT UINT32 *ListSize\r
1141 )\r
1142{\r
1143 UINT32 Index;\r
1144 SVfrDataType *pType;\r
1145\r
1146 if ((NameList == NULL) || (ListSize == NULL)) {\r
1147 return VFR_RETURN_FATAL_ERROR;\r
1148 }\r
1149\r
1150 *NameList = NULL;\r
1151 *ListSize = 0;\r
1152\r
1153 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1154 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1155 (*ListSize)++;\r
1156 }\r
1157 }\r
1158\r
1159 if (*ListSize == 0) {\r
1160 return VFR_RETURN_SUCCESS;\r
1161 }\r
1162\r
1163 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {\r
1164 *ListSize = 0;\r
1165 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1166 }\r
1167\r
1168 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {\r
1169 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1170 (*NameList)[Index] = pType->mTypeName;\r
1171 }\r
1172 }\r
1173 return VFR_RETURN_SUCCESS;\r
1174}\r
1175\r
1176BOOLEAN\r
1177CVfrVarDataTypeDB::IsTypeNameDefined (\r
1178 IN CHAR8 *TypeName\r
1179 )\r
1180{\r
1181 SVfrDataType *pType;\r
1182\r
1183 if (TypeName == NULL) {\r
1184 return FALSE;\r
1185 }\r
1186\r
1187 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1188 if (strcmp (pType->mTypeName, TypeName) == 0) {\r
1189 return TRUE;\r
1190 }\r
1191 }\r
1192\r
1193 return FALSE;\r
1194}\r
1195\r
1196VOID\r
1197CVfrVarDataTypeDB::Dump (\r
1198 IN FILE *File\r
1199 )\r
1200{\r
1201 SVfrDataType *pTNode;\r
1202 SVfrDataField *pFNode;\r
1203\r
1204 fprintf (File, "\n\n***************************************************************\n");\r
1205 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);\r
1206 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1207 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1208 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);\r
1209 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1210 if (pFNode->mArrayNum > 0) {\r
1211 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1212 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);\r
1213 } else {\r
1214 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1215 pFNode->mFieldName, pFNode->mFieldType->mTypeName);\r
1216 }\r
1217 }\r
1218 fprintf (File, "\t\t};\n");\r
1219 fprintf (File, "---------------------------------------------------------------\n");\r
1220 }\r
1221 fprintf (File, "***************************************************************\n");\r
1222}\r
1223\r
1224#ifdef CVFR_VARDATATYPEDB_DEBUG\r
1225VOID\r
1226CVfrVarDataTypeDB::ParserDB (\r
1227 VOID\r
1228 )\r
1229{\r
1230 SVfrDataType *pTNode;\r
1231 SVfrDataField *pFNode;\r
1232\r
1233 printf ("***************************************************************\n");\r
1234 printf ("\t\tmPackAlign = %x\n", mPackAlign);\r
1235 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1236 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1237 printf ("\t\tstruct %s {\n", pTNode->mTypeName);\r
1238 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1239 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
1240 }\r
1241 printf ("\t\t};\n");\r
1242 printf ("---------------------------------------------------------------\n");\r
1243 }\r
1244 printf ("***************************************************************\n");\r
1245}\r
1246#endif\r
1247\r
1248SVfrVarStorageNode::SVfrVarStorageNode (\r
1249 IN EFI_GUID *Guid,\r
1250 IN CHAR8 *StoreName,\r
1251 IN EFI_VARSTORE_ID VarStoreId,\r
1252 IN EFI_STRING_ID VarName,\r
1253 IN UINT32 VarSize,\r
1254 IN BOOLEAN Flag\r
1255 )\r
1256{\r
1257 if (Guid != NULL) {\r
1258 mGuid = *Guid;\r
1259 } else {\r
1260 memset (&Guid, 0, sizeof (EFI_GUID));\r
1261 }\r
1262 if (StoreName != NULL) {\r
1263 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1264 strcpy (mVarStoreName, StoreName);\r
1265 } else {\r
1266 mVarStoreName = NULL;\r
1267 }\r
1268 mNext = NULL;\r
1269 mVarStoreId = VarStoreId;\r
1270 mVarStoreType = EFI_VFR_VARSTORE_EFI;\r
1271 mStorageInfo.mEfiVar.mEfiVarName = VarName;\r
1272 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;\r
1273 mAssignedFlag = Flag;\r
1274}\r
1275\r
1276SVfrVarStorageNode::SVfrVarStorageNode (\r
1277 IN EFI_GUID *Guid,\r
1278 IN CHAR8 *StoreName,\r
1279 IN EFI_VARSTORE_ID VarStoreId,\r
1280 IN SVfrDataType *DataType,\r
1281 IN BOOLEAN Flag\r
1282 )\r
1283{\r
1284 if (Guid != NULL) {\r
1285 mGuid = *Guid;\r
1286 } else {\r
1287 memset (&Guid, 0, sizeof (EFI_GUID));\r
1288 }\r
1289 if (StoreName != NULL) {\r
1290 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1291 strcpy (mVarStoreName, StoreName);\r
1292 } else {\r
1293 mVarStoreName = NULL;\r
1294 }\r
1295 mNext = NULL;\r
1296 mVarStoreId = VarStoreId;\r
1297 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
1298 mStorageInfo.mDataType = DataType;\r
1299 mAssignedFlag = Flag;\r
1300}\r
1301\r
1302SVfrVarStorageNode::SVfrVarStorageNode (\r
1303 IN CHAR8 *StoreName,\r
1304 IN EFI_VARSTORE_ID VarStoreId\r
1305 )\r
1306{\r
1307 if (StoreName != NULL) {\r
1308 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1309 strcpy (mVarStoreName, StoreName);\r
1310 } else {\r
1311 mVarStoreName = NULL;\r
1312 }\r
1313 mNext = NULL;\r
1314 mVarStoreId = VarStoreId;\r
1315 mVarStoreType = EFI_VFR_VARSTORE_NAME;\r
1316 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
1317 mStorageInfo.mNameSpace.mTableSize = 0;\r
1318}\r
1319\r
1320SVfrVarStorageNode::~SVfrVarStorageNode (\r
1321 VOID\r
1322 )\r
1323{\r
1324 if (mVarStoreName != NULL) {\r
1325 delete mVarStoreName;\r
1326 }\r
1327\r
1328 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
1329 delete mStorageInfo.mNameSpace.mNameTable;\r
1330 }\r
1331}\r
1332\r
1333CVfrDataStorage::CVfrDataStorage (\r
1334 VOID\r
1335 )\r
1336{\r
1337 UINT32 Index;\r
1338\r
1339 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1340 mFreeVarStoreIdBitMap[Index] = 0;\r
1341 }\r
1342\r
1343 // Question ID 0 is reserved.\r
1344 mFreeVarStoreIdBitMap[0] = 0x80000000;\r
1345\r
1346 mBufferVarStoreList = NULL;\r
1347 mEfiVarStoreList = NULL;\r
1348 mNameVarStoreList = NULL;\r
1349 mCurrVarStorageNode = NULL;\r
1350 mNewVarStorageNode = NULL;\r
1351}\r
1352\r
1353CVfrDataStorage::~CVfrDataStorage (\r
1354 VOID\r
1355 )\r
1356{\r
1357 SVfrVarStorageNode *pNode;\r
1358\r
1359 while (mBufferVarStoreList != NULL) {\r
1360 pNode = mBufferVarStoreList;\r
1361 mBufferVarStoreList = mBufferVarStoreList->mNext;\r
1362 delete pNode;\r
1363 }\r
1364 while (mEfiVarStoreList != NULL) {\r
1365 pNode = mEfiVarStoreList;\r
1366 mEfiVarStoreList = mEfiVarStoreList->mNext;\r
1367 delete pNode;\r
1368 }\r
1369 while (mNameVarStoreList != NULL) {\r
1370 pNode = mNameVarStoreList;\r
1371 mNameVarStoreList = mNameVarStoreList->mNext;\r
1372 delete pNode;\r
1373 }\r
1374 if (mNewVarStorageNode != NULL) {\r
1375 delete mNewVarStorageNode;\r
1376 }\r
1377}\r
1378\r
1379EFI_VARSTORE_ID\r
1380CVfrDataStorage::GetFreeVarStoreId (\r
1381 EFI_VFR_VARSTORE_TYPE VarType\r
1382 )\r
1383{\r
1384 UINT32 Index, Mask, Offset;\r
1385 \r
1386 //\r
1387 // Assign the different ID range for the different type VarStore to support Framework Vfr\r
1388 //\r
1389 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {\r
1390 Index = 0;\r
1391 } else if (VarType == EFI_VFR_VARSTORE_EFI) {\r
1392 Index = 1;\r
1393 } else if (VarType == EFI_VFR_VARSTORE_NAME) {\r
1394 Index = 2;\r
1395 }\r
1396\r
1397 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1398 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {\r
1399 break;\r
1400 }\r
1401 }\r
1402\r
1403 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
1404 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
1405 mFreeVarStoreIdBitMap[Index] |= Mask;\r
1406 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
1407 }\r
1408 }\r
1409\r
1410 return EFI_VARSTORE_ID_INVALID;\r
1411}\r
1412\r
1413BOOLEAN\r
1414CVfrDataStorage::ChekVarStoreIdFree (\r
1415 IN EFI_VARSTORE_ID VarStoreId\r
1416 )\r
1417{\r
1418 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1419 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1420\r
1421 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
1422}\r
1423\r
1424VOID\r
1425CVfrDataStorage::MarkVarStoreIdUsed (\r
1426 IN EFI_VARSTORE_ID VarStoreId\r
1427 )\r
1428{\r
1429 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1430 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1431\r
1432 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
1433}\r
1434\r
1435VOID\r
1436CVfrDataStorage::MarkVarStoreIdUnused (\r
1437 IN EFI_VARSTORE_ID VarStoreId\r
1438 )\r
1439{\r
1440 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1441 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1442\r
1443 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
1444}\r
1445\r
1446EFI_VFR_RETURN_CODE\r
1447CVfrDataStorage::DeclareNameVarStoreBegin (\r
1448 IN CHAR8 *StoreName\r
1449 )\r
1450{\r
1451 SVfrVarStorageNode *pNode = NULL;\r
1452 EFI_VARSTORE_ID VarStoreId;\r
1453\r
1454 if (StoreName == NULL) {\r
1455 return VFR_RETURN_FATAL_ERROR;\r
1456 }\r
1457\r
1458 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1459 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1460 return VFR_RETURN_REDEFINED;\r
1461 }\r
1462 }\r
1463\r
1464 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
1465 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
1466 return VFR_RETURN_UNDEFINED;\r
1467 }\r
1468\r
1469 mNewVarStorageNode = pNode;\r
1470\r
1471 return VFR_RETURN_SUCCESS;\r
1472}\r
1473\r
1474EFI_VFR_RETURN_CODE\r
1475CVfrDataStorage::NameTableAddItem (\r
1476 IN EFI_STRING_ID Item\r
1477 )\r
1478{\r
1479 EFI_VARSTORE_ID *NewTable, *OldTable;\r
1480 UINT32 TableSize;\r
1481\r
1482 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
1483 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
1484\r
1485 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
1486 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
1487 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1488 }\r
1489 memcpy (NewTable, OldTable, TableSize);\r
1490 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
1491 }\r
1492\r
1493 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
1494 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
1495\r
1496 return VFR_RETURN_SUCCESS;\r
1497}\r
1498\r
1499EFI_VFR_RETURN_CODE\r
1500CVfrDataStorage::DeclareNameVarStoreEnd (\r
1501 IN EFI_GUID *Guid\r
1502 )\r
1503{\r
1504 mNewVarStorageNode->mGuid = *Guid;\r
1505 mNewVarStorageNode->mNext = mNameVarStoreList;\r
1506 mNameVarStoreList = mNewVarStorageNode;\r
1507\r
1508 mNewVarStorageNode = NULL;\r
1509\r
1510 return VFR_RETURN_SUCCESS;\r
1511}\r
1512\r
1513EFI_VFR_RETURN_CODE \r
1514CVfrDataStorage::DeclareEfiVarStore (\r
1515 IN CHAR8 *StoreName, \r
1516 IN EFI_GUID *Guid, \r
1517 IN EFI_STRING_ID NameStrId,\r
1518 IN UINT32 VarSize,\r
1519 IN BOOLEAN Flag\r
1520 )\r
1521{\r
1522 SVfrVarStorageNode *pNode;\r
1523 EFI_VARSTORE_ID VarStoreId;\r
1524\r
1525 if ((StoreName == NULL) || (Guid == NULL)) {\r
1526 return VFR_RETURN_FATAL_ERROR;\r
1527 }\r
1528\r
1529 if (VarSize > sizeof (UINT64)) {\r
1530 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
1531 }\r
1532\r
1533 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1534 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1535 return VFR_RETURN_REDEFINED;\r
1536 }\r
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
1562\r
1563 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1564 return VFR_RETURN_FATAL_ERROR;\r
1565 }\r
1566\r
1567 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
1568\r
1569 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1570 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);\r
1571 } else {\r
1572 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1573 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1574 }\r
1575 MarkVarStoreIdUsed (VarStoreId);\r
1576 }\r
1577\r
1578 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
1579 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1580 }\r
1581\r
1582 pNew->mNext = mBufferVarStoreList;\r
1583 mBufferVarStoreList = pNew;\r
1584\r
1585 if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
1586 return VFR_RETURN_FATAL_ERROR;\r
1587 }\r
1588\r
1589 return VFR_RETURN_SUCCESS;\r
1590}\r
1591\r
1592EFI_VFR_RETURN_CODE \r
1593CVfrDataStorage::GetVarStoreId (\r
1594 IN CHAR8 *StoreName,\r
1595 OUT EFI_VARSTORE_ID *VarStoreId\r
1596 )\r
1597{\r
1598 SVfrVarStorageNode *pNode;\r
1599\r
1600 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1601 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1602 mCurrVarStorageNode = pNode;\r
1603 *VarStoreId = pNode->mVarStoreId;\r
1604 return VFR_RETURN_SUCCESS;\r
1605 }\r
1606 }\r
1607\r
1608 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1609 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1610 mCurrVarStorageNode = pNode;\r
1611 *VarStoreId = pNode->mVarStoreId;\r
1612 return VFR_RETURN_SUCCESS;\r
1613 }\r
1614 }\r
1615\r
1616 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1617 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1618 mCurrVarStorageNode = pNode;\r
1619 *VarStoreId = pNode->mVarStoreId;\r
1620 return VFR_RETURN_SUCCESS;\r
1621 }\r
1622 }\r
1623\r
1624 mCurrVarStorageNode = NULL;\r
1625 *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
1626 return VFR_RETURN_UNDEFINED;\r
1627}\r
1628\r
1629EFI_VFR_RETURN_CODE\r
1630CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
1631 IN CHAR8 *StoreName,\r
1632 OUT CHAR8 **DataTypeName\r
1633 )\r
1634{\r
1635 SVfrVarStorageNode *pNode;\r
1636\r
1637 if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
1638 return VFR_RETURN_FATAL_ERROR;\r
1639 }\r
1640\r
1641 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1642 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1643 break;\r
1644 }\r
1645 }\r
1646\r
1647 if (pNode == NULL) {\r
1648 return VFR_RETURN_UNDEFINED;\r
1649 }\r
1650\r
1651 if (pNode->mStorageInfo.mDataType == NULL) {\r
1652 return VFR_RETURN_FATAL_ERROR;\r
1653 }\r
1654\r
1655 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
1656 return VFR_RETURN_SUCCESS;\r
1657}\r
1658\r
1659EFI_VFR_RETURN_CODE\r
1660CVfrDataStorage::GetVarStoreType (\r
1661 IN CHAR8 *StoreName,\r
1662 OUT EFI_VFR_VARSTORE_TYPE &VarStoreType\r
1663 )\r
1664{\r
1665 SVfrVarStorageNode *pNode;\r
1666\r
1667 if (StoreName == NULL) {\r
1668 return VFR_RETURN_FATAL_ERROR;\r
1669 }\r
1670\r
1671 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
df1780f8 1672 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
1673 VarStoreType = pNode->mVarStoreType;\r
1674 return VFR_RETURN_SUCCESS;\r
1675 }\r
1676 }\r
1677\r
1678 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
df1780f8 1679 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
1680 VarStoreType = pNode->mVarStoreType;\r
1681 return VFR_RETURN_SUCCESS;\r
1682 }\r
1683 }\r
1684\r
1685 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
df1780f8 1686 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
1687 VarStoreType = pNode->mVarStoreType;\r
1688 return VFR_RETURN_SUCCESS;\r
1689 }\r
1690 }\r
1691\r
1692 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1693 return VFR_RETURN_UNDEFINED;\r
1694}\r
1695\r
1696EFI_VFR_VARSTORE_TYPE\r
1697CVfrDataStorage::GetVarStoreType (\r
1698 IN EFI_VARSTORE_ID VarStoreId\r
1699 )\r
1700{\r
1701 SVfrVarStorageNode *pNode;\r
1702 EFI_VFR_VARSTORE_TYPE VarStoreType;\r
1703\r
1704 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1705\r
1706 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1707 return VarStoreType;\r
1708 }\r
1709\r
1710 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1711 if (pNode->mVarStoreId == VarStoreId) {\r
1712 VarStoreType = pNode->mVarStoreType;\r
1713 return VarStoreType;\r
1714 }\r
1715 }\r
1716\r
1717 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1718 if (pNode->mVarStoreId == VarStoreId) {\r
1719 VarStoreType = pNode->mVarStoreType;\r
1720 return VarStoreType;\r
1721 }\r
1722 }\r
1723\r
1724 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1725 if (pNode->mVarStoreId == VarStoreId) {\r
1726 VarStoreType = pNode->mVarStoreType;\r
1727 return VarStoreType;\r
1728 }\r
1729 }\r
1730\r
1731 return VarStoreType;\r
1732}\r
1733\r
1734EFI_VFR_RETURN_CODE\r
1735CVfrDataStorage::GetVarStoreName (\r
1736 IN EFI_VARSTORE_ID VarStoreId, \r
1737 OUT CHAR8 **VarStoreName\r
1738 )\r
1739{\r
1740 SVfrVarStorageNode *pNode;\r
1741\r
1742 if (VarStoreName == NULL) {\r
1743 return VFR_RETURN_FATAL_ERROR;\r
1744 }\r
1745\r
1746 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1747 if (pNode->mVarStoreId == VarStoreId) {\r
1748 *VarStoreName = pNode->mVarStoreName;\r
1749 return VFR_RETURN_SUCCESS;\r
1750 }\r
1751 }\r
1752\r
1753 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1754 if (pNode->mVarStoreId == VarStoreId) {\r
1755 *VarStoreName = pNode->mVarStoreName;\r
1756 return VFR_RETURN_SUCCESS;\r
1757 }\r
1758 }\r
1759\r
1760 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1761 if (pNode->mVarStoreId == VarStoreId) {\r
1762 *VarStoreName = pNode->mVarStoreName;\r
1763 return VFR_RETURN_SUCCESS;\r
1764 }\r
1765 }\r
1766\r
1767 *VarStoreName = NULL;\r
1768 return VFR_RETURN_UNDEFINED;\r
1769}\r
1770\r
1771EFI_VFR_RETURN_CODE\r
1772CVfrDataStorage::GetEfiVarStoreInfo (\r
1773 IN OUT EFI_VARSTORE_INFO *Info\r
1774 )\r
1775{\r
1776 if (Info == NULL) {\r
1777 return VFR_RETURN_FATAL_ERROR;\r
1778 }\r
1779\r
1780 if (mCurrVarStorageNode == NULL) {\r
1781 return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
1782 }\r
1783\r
1784 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
1785 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
1786 switch (Info->mVarTotalSize) {\r
1787 case 1:\r
1788 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
1789 break;\r
1790 case 2:\r
1791 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
1792 break;\r
1793 case 4:\r
1794 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
1795 break;\r
1796 case 8:\r
1797 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
1798 break;\r
1799 default :\r
1800 return VFR_RETURN_FATAL_ERROR;\r
1801 }\r
1802\r
1803 return VFR_RETURN_SUCCESS;\r
1804}\r
1805\r
1806EFI_VFR_RETURN_CODE\r
1807CVfrDataStorage::GetNameVarStoreInfo (\r
1808 OUT EFI_VARSTORE_INFO *Info,\r
1809 IN UINT32 Index\r
1810 )\r
1811{\r
1812 if (Info == NULL) {\r
1813 return VFR_RETURN_FATAL_ERROR;\r
1814 }\r
1815\r
1816 if (mCurrVarStorageNode == NULL) {\r
1817 return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
1818 }\r
1819 \r
1820 //\r
1821 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
1822 //\r
1823 if (VfrCompatibleMode) {\r
1824 if (Index == 0) {\r
1825 return VFR_RETURN_ERROR_ARRARY_NUM;\r
1826 }\r
1827 Index --;\r
1828 }\r
1829\r
1830 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
1831\r
1832 return VFR_RETURN_SUCCESS;\r
1833}\r
1834\r
1835EFI_VFR_RETURN_CODE\r
1836CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
1837 IN CHAR8 *StoreName,\r
1838 IN EFI_VARSTORE_INFO &Info\r
1839 )\r
1840{\r
1841 CHAR8 NewReqElt[128] = {'\0',};\r
1842 CHAR8 *OldReqElt = NULL;\r
1843 SVfrVarStorageNode *pNode = NULL;\r
1844 EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;\r
1845\r
1846 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1847 if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1848 break;\r
1849 }\r
1850 }\r
1851\r
1852 if (pNode == NULL) {\r
1853 return VFR_RETURN_UNDEFINED;\r
1854 }\r
1855\r
1856 gCVfrBufferConfig.Open ();\r
1857 Value.u8 = 0;\r
1858 if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
1859 return VFR_RETURN_FATAL_ERROR;\r
1860 }\r
1861 gCVfrBufferConfig.Close ();\r
1862\r
1863 return VFR_RETURN_SUCCESS;\r
1864}\r
1865\r
1866SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
1867 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
1868 IN CHAR8 *RefName, \r
1869 IN EFI_STRING_ID DefaultStoreNameId, \r
1870 IN UINT16 DefaultId\r
1871 )\r
1872{\r
1873 mObjBinAddr = ObjBinAddr;\r
1874\r
1875 if (RefName != NULL) {\r
1876 mRefName = new CHAR8[strlen (RefName) + 1];\r
1877 strcpy (mRefName, RefName);\r
1878 } else {\r
1879 mRefName = NULL;\r
1880 }\r
1881\r
1882 mNext = NULL;\r
1883 mDefaultId = DefaultId;\r
1884 mDefaultStoreNameId = DefaultStoreNameId;\r
1885}\r
1886\r
1887SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
1888 VOID\r
1889 )\r
1890{\r
1891 if (mRefName != NULL) {\r
1892 delete mRefName;\r
1893 }\r
1894}\r
1895\r
1896CVfrDefaultStore::CVfrDefaultStore (\r
1897 VOID\r
1898 )\r
1899{\r
1900 mDefaultStoreList = NULL;\r
1901}\r
1902\r
1903CVfrDefaultStore::~CVfrDefaultStore (\r
1904 VOID\r
1905 )\r
1906{\r
1907 SVfrDefaultStoreNode *pTmp = NULL;\r
1908\r
1909 while (mDefaultStoreList != NULL) {\r
1910 pTmp = mDefaultStoreList;\r
1911 mDefaultStoreList = mDefaultStoreList->mNext;\r
1912 delete pTmp;\r
1913 }\r
1914}\r
1915\r
1916EFI_VFR_RETURN_CODE\r
1917CVfrDefaultStore::RegisterDefaultStore (\r
1918 IN CHAR8 *ObjBinAddr,\r
1919 IN CHAR8 *RefName,\r
1920 IN EFI_STRING_ID DefaultStoreNameId,\r
1921 IN UINT16 DefaultId\r
1922 )\r
1923{\r
1924 SVfrDefaultStoreNode *pNode = NULL;\r
1925\r
1926 if (RefName == NULL) {\r
1927 return VFR_RETURN_FATAL_ERROR;\r
1928 }\r
1929\r
1930 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1931 if (strcmp (pNode->mRefName, RefName) == 0) {\r
1932 return VFR_RETURN_REDEFINED;\r
1933 }\r
1934 }\r
1935\r
1936 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
1937 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1938 }\r
1939\r
1940 pNode->mNext = mDefaultStoreList;\r
1941 mDefaultStoreList = pNode;\r
1942\r
1943 return VFR_RETURN_SUCCESS;\r
1944}\r
1945\r
1946/*\r
1947 * assign new reference name or new default store name id only if \r
1948 * the original is invalid\r
1949 */\r
1950EFI_VFR_RETURN_CODE\r
1951CVfrDefaultStore::ReRegisterDefaultStoreById (\r
1952 IN UINT16 DefaultId,\r
1953 IN CHAR8 *RefName,\r
1954 IN EFI_STRING_ID DefaultStoreNameId\r
1955 )\r
1956{\r
1957 SVfrDefaultStoreNode *pNode = NULL;\r
1958\r
1959 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1960 if (pNode->mDefaultId == DefaultId) {\r
1961 break;\r
1962 }\r
1963 }\r
1964\r
1965 if (pNode == NULL) {\r
1966 return VFR_RETURN_UNDEFINED;\r
1967 } else {\r
1968 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
1969 pNode->mDefaultStoreNameId = DefaultStoreNameId;\r
1970 if (pNode->mObjBinAddr != NULL) {\r
1971 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
1972 }\r
1973 } else {\r
1974 return VFR_RETURN_REDEFINED;\r
1975 }\r
1976\r
1977 if (RefName != NULL) {\r
1978 delete pNode->mRefName;\r
1979 pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
1980 if (pNode->mRefName != NULL) {\r
1981 strcpy (pNode->mRefName, RefName);\r
1982 }\r
1983 }\r
1984 }\r
1985\r
1986 return VFR_RETURN_SUCCESS;\r
1987}\r
1988\r
1989BOOLEAN\r
1990CVfrDefaultStore::DefaultIdRegistered (\r
1991 IN UINT16 DefaultId\r
1992 )\r
1993{\r
1994 SVfrDefaultStoreNode *pNode = NULL;\r
1995\r
1996 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1997 if (pNode->mDefaultId == DefaultId) {\r
1998 return TRUE;\r
1999 }\r
2000 }\r
2001\r
2002 return FALSE;\r
2003}\r
2004\r
2005EFI_VFR_RETURN_CODE\r
2006CVfrDefaultStore::GetDefaultId (\r
2007 IN CHAR8 *RefName,\r
2008 OUT UINT16 *DefaultId\r
2009 )\r
2010{\r
2011 SVfrDefaultStoreNode *pTmp = NULL;\r
2012\r
2013 if (DefaultId == NULL) {\r
2014 return VFR_RETURN_FATAL_ERROR;\r
2015 }\r
2016\r
2017 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
2018 if (strcmp (pTmp->mRefName, RefName) == 0) {\r
2019 *DefaultId = pTmp->mDefaultId;\r
2020 return VFR_RETURN_SUCCESS;\r
2021 }\r
2022 }\r
2023\r
2024 return VFR_RETURN_UNDEFINED;\r
2025}\r
2026\r
2027STATIC\r
2028EFI_VFR_RETURN_CODE\r
2029AltCfgItemPrintToBuffer (\r
2030 IN CHAR8 *NewAltCfg, \r
2031 IN EFI_VARSTORE_INFO Info, \r
2032 IN UINT8 Type,\r
2033 IN EFI_IFR_TYPE_VALUE Value\r
2034 )\r
2035{\r
2036 UINT32 Index;\r
2037 UINT8 *BufChar = NULL;\r
2038 UINT32 Count = 0;\r
2039\r
2040 if (NewAltCfg != NULL) {\r
2041 Count = sprintf (\r
2042 NewAltCfg,\r
2043 "&OFFSET=%x&WIDTH=%x&VALUE=",\r
2044 Info.mInfo.mVarOffset,\r
2045 Info.mVarTotalSize\r
2046 );\r
2047 NewAltCfg += Count;\r
2048\r
2049 switch (Type) {\r
2050 case EFI_IFR_TYPE_NUM_SIZE_8 :\r
2051 Count = sprintf (NewAltCfg, "%x", Value.u8);\r
2052 NewAltCfg += Count;\r
2053 break;\r
2054 case EFI_IFR_TYPE_NUM_SIZE_16 :\r
2055 Count = sprintf (NewAltCfg, "%x", Value.u16);\r
2056 NewAltCfg += Count;\r
2057 break;\r
2058 case EFI_IFR_TYPE_NUM_SIZE_32 :\r
2059 Count = sprintf (NewAltCfg, "%x", Value.u32);\r
2060 NewAltCfg += Count;\r
2061 break;\r
2062 case EFI_IFR_TYPE_NUM_SIZE_64 :\r
2063 Count = sprintf (NewAltCfg, "%x", Value.u64);\r
2064 NewAltCfg += Count;\r
2065 break;\r
2066 case EFI_IFR_TYPE_BOOLEAN :\r
2067 Count = sprintf (NewAltCfg, "%x", Value.b);\r
2068 NewAltCfg += Count;\r
2069 break;\r
2070 case EFI_IFR_TYPE_TIME :\r
2071#if 1\r
2072 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));\r
2073 NewAltCfg += Count;\r
2074#else\r
2075 BufChar = (UINT8 *)&Value.time;\r
2076 for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {\r
2077 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
2078 NewAltCfg += Count;\r
2079 }\r
2080#endif\r
2081 break;\r
2082 case EFI_IFR_TYPE_DATE :\r
2083#if 1\r
2084 Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));\r
2085 NewAltCfg += Count;\r
2086#else\r
2087 BufChar = (UINT8 *)&Value.date;\r
2088 for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {\r
2089 Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
2090 NewAltCfg += Count;\r
2091 }\r
2092#endif\r
2093 break;\r
2094 case EFI_IFR_TYPE_STRING :\r
2095 Count = sprintf (NewAltCfg, "%x", Value.string);\r
2096 NewAltCfg += Count;\r
2097 break;\r
2098 case EFI_IFR_TYPE_OTHER :\r
2099 return VFR_RETURN_UNSUPPORTED;\r
2100 }\r
2101 }\r
2102\r
2103 return VFR_RETURN_FATAL_ERROR;\r
2104}\r
2105\r
2106EFI_VFR_RETURN_CODE\r
2107CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2108 IN EFI_VARSTORE_ID DefaultId,\r
2109 IN EFI_VARSTORE_INFO &Info,\r
2110 IN CHAR8 *VarStoreName,\r
2111 IN UINT8 Type,\r
2112 IN EFI_IFR_TYPE_VALUE Value\r
2113 )\r
2114{\r
2115 SVfrDefaultStoreNode *pNode = NULL;\r
2116 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2117 INTN Returnvalue = 0;\r
2118\r
2119 if (VarStoreName == NULL) {\r
2120 return VFR_RETURN_FATAL_ERROR;\r
2121 }\r
2122\r
2123 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2124 if (pNode->mDefaultId == DefaultId) {\r
2125 break;\r
2126 }\r
2127 }\r
2128\r
2129 if (pNode == NULL) {\r
2130 return VFR_RETURN_UNDEFINED;\r
2131 }\r
2132\r
2133 gCVfrBufferConfig.Open ();\r
2134\r
2135 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
2136 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
2137 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
2138 goto WriteError;\r
2139 }\r
2140 }\r
2141 \r
2142 gCVfrBufferConfig.Close ();\r
2143\r
2144 return VFR_RETURN_SUCCESS;\r
2145\r
2146WriteError:\r
2147 gCVfrBufferConfig.Close ();\r
2148 return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2149}\r
2150\r
2151SVfrRuleNode::SVfrRuleNode (\r
2152 IN CHAR8 *RuleName,\r
2153 IN UINT8 RuleId\r
2154 )\r
2155{\r
2156 if (RuleName != NULL) {\r
2157 mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2158 strcpy (mRuleName, RuleName);\r
2159 } else {\r
2160 mRuleName = NULL;\r
2161 }\r
2162\r
2163 mNext = NULL;\r
2164 mRuleId = RuleId;\r
2165}\r
2166\r
2167SVfrRuleNode::~SVfrRuleNode (\r
2168 VOID\r
2169 )\r
2170{\r
2171 if (mRuleName != NULL) {\r
2172 delete mRuleName;\r
2173 }\r
2174}\r
2175\r
2176CVfrRulesDB::CVfrRulesDB ()\r
2177{\r
2178 mRuleList = NULL;\r
2179 mFreeRuleId = EFI_VARSTORE_ID_START;\r
2180}\r
2181\r
2182CVfrRulesDB::~CVfrRulesDB ()\r
2183{\r
2184 SVfrRuleNode *pNode;\r
2185\r
2186 while(mRuleList != NULL) {\r
2187 pNode = mRuleList;\r
2188 mRuleList = mRuleList->mNext;\r
2189 delete pNode;\r
2190 }\r
2191}\r
2192\r
2193VOID\r
2194CVfrRulesDB::RegisterRule (\r
2195 IN CHAR8 *RuleName\r
2196 )\r
2197{\r
2198 SVfrRuleNode *pNew;\r
2199\r
2200 if (RuleName == NULL) {\r
2201 return ;\r
2202 }\r
2203\r
2204 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2205 return ;\r
2206 }\r
2207\r
2208 mFreeRuleId++;\r
2209\r
2210 pNew->mNext = mRuleList;\r
2211 mRuleList = pNew;\r
2212}\r
2213\r
2214UINT8\r
2215CVfrRulesDB::GetRuleId (\r
2216 IN CHAR8 *RuleName\r
2217 )\r
2218{\r
2219 SVfrRuleNode *pNode;\r
2220\r
2221 if (RuleName == NULL) {\r
2222 return EFI_RULE_ID_INVALID;\r
2223 }\r
2224\r
2225 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2226 if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2227 return pNode->mRuleId;\r
2228 }\r
2229 }\r
2230\r
2231 return EFI_RULE_ID_INVALID;\r
2232}\r
2233\r
2234CVfrRulesDB gCVfrRulesDB;\r
2235\r
2236EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2237 VOID\r
2238 )\r
2239{\r
2240 mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2241 mInfo.mVarName = EFI_STRING_ID_INVALID;\r
2242 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2243 mVarType = EFI_IFR_TYPE_OTHER;\r
2244 mVarTotalSize = 0;\r
2245}\r
2246\r
2247EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2248 IN EFI_VARSTORE_INFO &Info\r
2249 )\r
2250{\r
2251 mVarStoreId = Info.mVarStoreId;\r
2252 mInfo.mVarName = Info.mInfo.mVarName;\r
2253 mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2254 mVarType = Info.mVarType;\r
2255 mVarTotalSize = Info.mVarTotalSize;\r
2256}\r
2257\r
2258BOOLEAN\r
2259EFI_VARSTORE_INFO::operator == (\r
2260 IN EFI_VARSTORE_INFO *Info\r
2261 )\r
2262{\r
2263 if ((mVarStoreId == Info->mVarStoreId) &&\r
2264 (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2265 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2266 (mVarType == Info->mVarType) &&\r
2267 (mVarTotalSize == Info->mVarTotalSize)) {\r
2268 return TRUE;\r
2269 }\r
2270\r
2271 return FALSE;\r
2272}\r
2273\r
2274static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2275\r
2276EFI_QUESTION_ID\r
2277CVfrQuestionDB::GetFreeQuestionId (\r
2278 VOID\r
2279 )\r
2280{\r
2281 UINT32 Index, Mask, Offset;\r
2282\r
2283 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2284 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2285 break;\r
2286 }\r
2287 }\r
2288\r
2289 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2290 if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2291 mFreeQIdBitMap[Index] |= Mask;\r
2292 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2293 }\r
2294 }\r
2295\r
2296 return EFI_QUESTION_ID_INVALID;\r
2297}\r
2298\r
2299BOOLEAN\r
2300CVfrQuestionDB::ChekQuestionIdFree (\r
2301 IN EFI_QUESTION_ID QId\r
2302 )\r
2303{\r
2304 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2305 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2306\r
2307 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2308}\r
2309\r
2310VOID\r
2311CVfrQuestionDB::MarkQuestionIdUsed (\r
2312 IN EFI_QUESTION_ID QId\r
2313 )\r
2314{\r
2315 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2316 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2317\r
2318 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2319}\r
2320\r
2321VOID\r
2322CVfrQuestionDB::MarkQuestionIdUnused (\r
2323 IN EFI_QUESTION_ID QId\r
2324 )\r
2325{\r
2326 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2327 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2328\r
2329 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2330}\r
2331\r
2332SVfrQuestionNode::SVfrQuestionNode (\r
2333 IN CHAR8 *Name,\r
2334 IN CHAR8 *VarIdStr,\r
2335 IN UINT32 BitMask\r
2336 )\r
2337{\r
2338 mName = NULL;\r
2339 mVarIdStr = NULL;\r
2340 mQuestionId = EFI_QUESTION_ID_INVALID;\r
2341 mBitMask = BitMask;\r
2342 mNext = NULL;\r
2343\r
2344 if (Name == NULL) {\r
2345 mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2346 strcpy (mName, "$DEFAULT");\r
2347 } else {\r
2348 mName = new CHAR8[strlen (Name) + 1];\r
2349 strcpy (mName, Name);\r
2350 }\r
2351\r
2352 if (VarIdStr != NULL) {\r
2353 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2354 strcpy (mVarIdStr, VarIdStr);\r
2355 } else {\r
2356 mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2357 strcpy (mVarIdStr, "$");\r
2358 }\r
2359}\r
2360\r
2361SVfrQuestionNode::~SVfrQuestionNode (\r
2362 VOID\r
2363 )\r
2364{\r
2365 if (mName != NULL) {\r
2366 delete mName;\r
2367 }\r
2368\r
2369 if (mVarIdStr != NULL) {\r
2370 delete mVarIdStr;\r
2371 }\r
2372}\r
2373\r
2374CVfrQuestionDB::CVfrQuestionDB ()\r
2375{\r
2376 UINT32 Index;\r
2377\r
2378 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2379 mFreeQIdBitMap[Index] = 0;\r
2380 }\r
2381\r
2382 // Question ID 0 is reserved.\r
2383 mFreeQIdBitMap[0] = 0x80000000;\r
2384 mQuestionList = NULL;\r
2385}\r
2386\r
2387CVfrQuestionDB::~CVfrQuestionDB ()\r
2388{\r
2389 SVfrQuestionNode *pNode;\r
2390\r
2391 while (mQuestionList != NULL) {\r
2392 pNode = mQuestionList;\r
2393 mQuestionList = mQuestionList->mNext;\r
2394 delete pNode;\r
2395 }\r
2396}\r
2397\r
2398//\r
2399// Reset to init state\r
2400//\r
2401VOID\r
2402CVfrQuestionDB::ResetInit(\r
2403 IN VOID\r
2404 )\r
2405{\r
2406 UINT32 Index;\r
2407 SVfrQuestionNode *pNode;\r
2408\r
2409 while (mQuestionList != NULL) {\r
2410 pNode = mQuestionList;\r
2411 mQuestionList = mQuestionList->mNext;\r
2412 delete pNode;\r
2413 }\r
2414\r
2415 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2416 mFreeQIdBitMap[Index] = 0;\r
2417 }\r
2418\r
2419 // Question ID 0 is reserved.\r
2420 mFreeQIdBitMap[0] = 0x80000000;\r
2421 mQuestionList = NULL; \r
2422}\r
2423\r
2424VOID\r
2425CVfrQuestionDB::PrintAllQuestion (\r
2426 VOID\r
2427 )\r
2428{\r
2429 SVfrQuestionNode *pNode = NULL;\r
2430\r
2431 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2432 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2433 }\r
2434}\r
2435\r
2436EFI_VFR_RETURN_CODE\r
2437CVfrQuestionDB::RegisterQuestion (\r
2438 IN CHAR8 *Name,\r
2439 IN CHAR8 *VarIdStr,\r
2440 IN OUT EFI_QUESTION_ID &QuestionId\r
2441 )\r
2442{\r
2443 SVfrQuestionNode *pNode = NULL;\r
2444\r
2445 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2446 return VFR_RETURN_REDEFINED;\r
2447 }\r
2448\r
2449 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2450 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2451 }\r
2452\r
2453 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2454 QuestionId = GetFreeQuestionId ();\r
2455 } else {\r
2456 //\r
2457 // For Framework Vfr, don't check question ID conflict.\r
2458 //\r
2459 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2460 delete pNode;\r
2461 return VFR_RETURN_QUESTIONID_REDEFINED;\r
2462 }\r
2463 MarkQuestionIdUsed (QuestionId);\r
2464 }\r
2465 pNode->mQuestionId = QuestionId;\r
2466\r
2467 pNode->mNext = mQuestionList;\r
2468 mQuestionList = pNode;\r
2469\r
2470 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2471\r
2472 return VFR_RETURN_SUCCESS;\r
2473}\r
2474\r
2475VOID\r
2476CVfrQuestionDB::RegisterOldDateQuestion (\r
2477 IN CHAR8 *YearVarId,\r
2478 IN CHAR8 *MonthVarId,\r
2479 IN CHAR8 *DayVarId,\r
2480 IN OUT EFI_QUESTION_ID &QuestionId\r
2481 )\r
2482{\r
2483 SVfrQuestionNode *pNode[3] = {NULL, };\r
2484 UINT32 Index;\r
2485\r
2486 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2487 return;\r
2488 }\r
2489\r
2490 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2491 goto Err;\r
2492 }\r
2493 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2494 goto Err;\r
2495 }\r
2496 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2497 goto Err;\r
2498 }\r
2499\r
2500 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2501 QuestionId = GetFreeQuestionId ();\r
2502 } else {\r
2503 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2504 goto Err;\r
2505 }\r
2506 MarkQuestionIdUsed (QuestionId);\r
2507 }\r
2508\r
2509 pNode[0]->mQuestionId = QuestionId;\r
2510 pNode[1]->mQuestionId = QuestionId;\r
2511 pNode[2]->mQuestionId = QuestionId;\r
2512 pNode[0]->mNext = pNode[1];\r
2513 pNode[1]->mNext = pNode[2];\r
2514 pNode[2]->mNext = mQuestionList;\r
2515 mQuestionList = pNode[0];\r
2516\r
2517 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2518 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2519 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2520\r
2521 return;\r
2522\r
2523Err:\r
2524 for (Index = 0; Index < 3; Index++) {\r
2525 if (pNode[Index] != NULL) {\r
2526 delete pNode[Index];\r
2527 }\r
2528 }\r
2529 QuestionId = EFI_QUESTION_ID_INVALID;\r
2530}\r
2531\r
2532VOID\r
2533CVfrQuestionDB::RegisterNewDateQuestion (\r
2534 IN CHAR8 *Name,\r
2535 IN CHAR8 *BaseVarId,\r
2536 IN OUT EFI_QUESTION_ID &QuestionId\r
2537 )\r
2538{\r
2539 SVfrQuestionNode *pNode[3] = {NULL, };\r
2540 UINT32 Len;\r
2541 CHAR8 *VarIdStr[3] = {NULL, };\r
2542 CHAR8 Index;\r
2543\r
2544 if (BaseVarId == NULL) {\r
2545 return;\r
2546 }\r
2547\r
2548 Len = strlen (BaseVarId);\r
2549\r
2550 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2551 if (VarIdStr[0] != NULL) {\r
2552 strcpy (VarIdStr[0], BaseVarId);\r
2553 strcat (VarIdStr[0], ".Year");\r
2554 }\r
2555 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2556 if (VarIdStr[1] != NULL) {\r
2557 strcpy (VarIdStr[1], BaseVarId);\r
2558 strcat (VarIdStr[1], ".Month");\r
2559 }\r
2560 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2561 if (VarIdStr[2] != NULL) {\r
2562 strcpy (VarIdStr[2], BaseVarId);\r
2563 strcat (VarIdStr[2], ".Day");\r
2564 }\r
2565\r
2566 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
2567 goto Err;\r
2568 }\r
2569 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
2570 goto Err;\r
2571 }\r
2572 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
2573 goto Err;\r
2574 }\r
2575\r
2576 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2577 QuestionId = GetFreeQuestionId ();\r
2578 } else {\r
2579 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2580 goto Err;\r
2581 }\r
2582 MarkQuestionIdUsed (QuestionId);\r
2583 }\r
2584\r
2585 pNode[0]->mQuestionId = QuestionId;\r
2586 pNode[1]->mQuestionId = QuestionId;\r
2587 pNode[2]->mQuestionId = QuestionId;\r
2588 pNode[0]->mNext = pNode[1];\r
2589 pNode[1]->mNext = pNode[2];\r
2590 pNode[2]->mNext = mQuestionList;\r
2591 mQuestionList = pNode[0];\r
2592\r
2593 for (Index = 0; Index < 3; Index++) {\r
2594 if (VarIdStr[Index] != NULL) {\r
2595 delete VarIdStr[Index];\r
2596 }\r
2597 }\r
2598\r
2599 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2600 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2601 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2602\r
2603 return;\r
2604\r
2605Err:\r
2606 for (Index = 0; Index < 3; Index++) {\r
2607 if (pNode[Index] != NULL) {\r
2608 delete pNode[Index];\r
2609 }\r
2610\r
2611 if (VarIdStr[Index] != NULL) {\r
2612 delete VarIdStr[Index];\r
2613 }\r
2614 }\r
2615}\r
2616\r
2617VOID\r
2618CVfrQuestionDB::RegisterOldTimeQuestion (\r
2619 IN CHAR8 *HourVarId,\r
2620 IN CHAR8 *MinuteVarId,\r
2621 IN CHAR8 *SecondVarId,\r
2622 IN OUT EFI_QUESTION_ID &QuestionId\r
2623 )\r
2624{\r
2625 SVfrQuestionNode *pNode[3] = {NULL, };\r
2626 UINT32 Index;\r
2627\r
2628 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
2629 return;\r
2630 }\r
2631\r
2632 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
2633 goto Err;\r
2634 }\r
2635 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
2636 goto Err;\r
2637 }\r
2638 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
2639 goto Err;\r
2640 }\r
2641\r
2642 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2643 QuestionId = GetFreeQuestionId ();\r
2644 } else {\r
2645 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2646 goto Err;\r
2647 }\r
2648 MarkQuestionIdUsed (QuestionId);\r
2649 }\r
2650\r
2651 pNode[0]->mQuestionId = QuestionId;\r
2652 pNode[1]->mQuestionId = QuestionId;\r
2653 pNode[2]->mQuestionId = QuestionId;\r
2654 pNode[0]->mNext = pNode[1];\r
2655 pNode[1]->mNext = pNode[2];\r
2656 pNode[2]->mNext = mQuestionList;\r
2657 mQuestionList = pNode[0];\r
2658\r
2659 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2660 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2661 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2662\r
2663 return;\r
2664\r
2665Err:\r
2666 for (Index = 0; Index < 3; Index++) {\r
2667 if (pNode[Index] != NULL) {\r
2668 delete pNode[Index];\r
2669 }\r
2670 }\r
2671 QuestionId = EFI_QUESTION_ID_INVALID;\r
2672}\r
2673\r
2674VOID\r
2675CVfrQuestionDB::RegisterNewTimeQuestion (\r
2676 IN CHAR8 *Name,\r
2677 IN CHAR8 *BaseVarId,\r
2678 IN OUT EFI_QUESTION_ID &QuestionId\r
2679 )\r
2680{\r
2681 SVfrQuestionNode *pNode[3] = {NULL, };\r
2682 UINT32 Len;\r
2683 CHAR8 *VarIdStr[3] = {NULL, };\r
2684 CHAR8 Index;\r
2685\r
2686 if (BaseVarId == NULL) {\r
2687 return;\r
2688 }\r
2689\r
2690 Len = strlen (BaseVarId);\r
2691\r
2692 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2693 if (VarIdStr[0] != NULL) {\r
2694 strcpy (VarIdStr[0], BaseVarId);\r
2695 strcat (VarIdStr[0], ".Hour");\r
2696 }\r
2697 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2698 if (VarIdStr[1] != NULL) {\r
2699 strcpy (VarIdStr[1], BaseVarId);\r
2700 strcat (VarIdStr[1], ".Minute");\r
2701 }\r
2702 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2703 if (VarIdStr[2] != NULL) {\r
2704 strcpy (VarIdStr[2], BaseVarId);\r
2705 strcat (VarIdStr[2], ".Second");\r
2706 }\r
2707\r
2708 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
2709 goto Err;\r
2710 }\r
2711 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
2712 goto Err;\r
2713 }\r
2714 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
2715 goto Err;\r
2716 }\r
2717\r
2718 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2719 QuestionId = GetFreeQuestionId ();\r
2720 } else {\r
2721 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2722 goto Err;\r
2723 }\r
2724 MarkQuestionIdUsed (QuestionId);\r
2725 }\r
2726\r
2727 pNode[0]->mQuestionId = QuestionId;\r
2728 pNode[1]->mQuestionId = QuestionId;\r
2729 pNode[2]->mQuestionId = QuestionId;\r
2730 pNode[0]->mNext = pNode[1];\r
2731 pNode[1]->mNext = pNode[2];\r
2732 pNode[2]->mNext = mQuestionList;\r
2733 mQuestionList = pNode[0];\r
2734\r
2735 for (Index = 0; Index < 3; Index++) {\r
2736 if (VarIdStr[Index] != NULL) {\r
2737 delete VarIdStr[Index];\r
2738 }\r
2739 }\r
2740\r
2741 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2742 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2743 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2744\r
2745 return;\r
2746\r
2747Err:\r
2748 for (Index = 0; Index < 3; Index++) {\r
2749 if (pNode[Index] != NULL) {\r
2750 delete pNode[Index];\r
2751 }\r
2752\r
2753 if (VarIdStr[Index] != NULL) {\r
2754 delete VarIdStr[Index];\r
2755 }\r
2756 }\r
2757}\r
2758\r
2759EFI_VFR_RETURN_CODE\r
2760CVfrQuestionDB::UpdateQuestionId (\r
2761 IN EFI_QUESTION_ID QId,\r
2762 IN EFI_QUESTION_ID NewQId\r
2763 )\r
2764{\r
2765 SVfrQuestionNode *pNode = NULL;\r
2766 \r
2767 if (QId == NewQId) {\r
2768 // don't update\r
2769 return VFR_RETURN_SUCCESS;\r
2770 }\r
2771 \r
2772 //\r
2773 // For Framework Vfr, don't check question ID conflict.\r
2774 // \r
2775 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
2776 return VFR_RETURN_REDEFINED;\r
2777 }\r
2778\r
2779 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2780 if (pNode->mQuestionId == QId) {\r
2781 break;\r
2782 }\r
2783 }\r
2784\r
2785 if (pNode == NULL) {\r
2786 return VFR_RETURN_UNDEFINED;\r
2787 }\r
2788\r
2789 MarkQuestionIdUnused (QId);\r
2790 pNode->mQuestionId = NewQId;\r
2791 MarkQuestionIdUsed (NewQId);\r
2792\r
2793 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
2794\r
2795 return VFR_RETURN_SUCCESS;\r
2796}\r
2797\r
2798VOID\r
2799CVfrQuestionDB::GetQuestionId (\r
2800 IN CHAR8 *Name,\r
2801 IN CHAR8 *VarIdStr,\r
2802 OUT EFI_QUESTION_ID &QuestionId,\r
2803 OUT UINT32 &BitMask\r
2804 )\r
2805{\r
2806 SVfrQuestionNode *pNode;\r
2807\r
2808 QuestionId = EFI_QUESTION_ID_INVALID;\r
2809 BitMask = 0x00000000;\r
2810\r
2811 if ((Name == NULL) && (VarIdStr == NULL)) {\r
2812 return ;\r
2813 }\r
2814\r
2815 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2816 if (Name != NULL) {\r
2817 if (strcmp (pNode->mName, Name) != 0) {\r
2818 continue;\r
2819 }\r
2820 }\r
2821\r
2822 if (VarIdStr != NULL) {\r
2823 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
2824 continue;\r
2825 }\r
2826 }\r
2827\r
2828 QuestionId = pNode->mQuestionId;\r
2829 BitMask = pNode->mBitMask;\r
2830 break;\r
2831 }\r
2832\r
2833 return ;\r
2834}\r
2835\r
2836EFI_VFR_RETURN_CODE\r
2837CVfrQuestionDB::FindQuestion (\r
2838 IN EFI_QUESTION_ID QuestionId\r
2839 )\r
2840{\r
2841 SVfrQuestionNode *pNode;\r
2842\r
2843 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2844 return VFR_RETURN_INVALID_PARAMETER;\r
2845 }\r
2846\r
2847 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2848 if (pNode->mQuestionId == QuestionId) {\r
2849 return VFR_RETURN_SUCCESS;\r
2850 }\r
2851 }\r
2852\r
2853 return VFR_RETURN_UNDEFINED;\r
2854}\r
2855\r
2856EFI_VFR_RETURN_CODE\r
2857CVfrQuestionDB::FindQuestion (\r
2858 IN CHAR8 *Name\r
2859 )\r
2860{\r
2861 SVfrQuestionNode *pNode;\r
2862\r
2863 if (Name == NULL) {\r
2864 return VFR_RETURN_FATAL_ERROR;\r
2865 }\r
2866\r
2867 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2868 if (strcmp (pNode->mName, Name) == 0) {\r
2869 return VFR_RETURN_SUCCESS;\r
2870 }\r
2871 }\r
2872\r
2873 return VFR_RETURN_UNDEFINED;\r
2874}\r
2875\r
2876BOOLEAN VfrCompatibleMode = FALSE;\r
2877\r
2878CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
2879\r