]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
... / ...
CommitLineData
1/** @file\r
2 \r
3 Vfr common library functions.\r
4\r
5Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
6This 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 CONST 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 CONST 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, (UINT16) 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 CONST 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 {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},\r
472 {NULL, EFI_IFR_TYPE_OTHER, 0, 0}\r
473};\r
474\r
475STATIC\r
476BOOLEAN\r
477_IS_INTERNAL_TYPE (\r
478 IN CHAR8 *TypeName\r
479 )\r
480{\r
481 UINT32 Index;\r
482\r
483 if (TypeName == NULL) {\r
484 return FALSE;\r
485 }\r
486\r
487 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
488 if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {\r
489 return TRUE;\r
490 }\r
491 }\r
492\r
493 return FALSE;\r
494}\r
495\r
496STATIC\r
497CHAR8 *\r
498TrimHex (\r
499 IN CHAR8 *Str,\r
500 OUT bool *IsHex\r
501 )\r
502{\r
503 *IsHex = FALSE;\r
504\r
505 while (*Str && *Str == ' ') {\r
506 Str++;\r
507 }\r
508 while (*Str && *Str == '0') {\r
509 Str++;\r
510 }\r
511 if (*Str && (*Str == 'x' || *Str == 'X')) {\r
512 Str++;\r
513 *IsHex = TRUE;\r
514 }\r
515\r
516 return Str;\r
517}\r
518\r
519UINT32\r
520_STR2U32 (\r
521 IN CHAR8 *Str\r
522 )\r
523{\r
524 bool IsHex;\r
525 UINT32 Value;\r
526 CHAR8 c;\r
527\r
528 Str = TrimHex (Str, &IsHex);\r
529 for (Value = 0; (c = *Str) != '\0'; Str++) {\r
530 //\r
531 // BUG: does not handle overflow here\r
532 //\r
533 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
534\r
535 if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
536 Value += (c - 'a' + 10);\r
537 }\r
538 if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
539 Value += (c - 'A' + 10);\r
540 }\r
541 if (c >= '0' && c <= '9') {\r
542 Value += (c - '0');\r
543 }\r
544 }\r
545\r
546 return Value;\r
547}\r
548\r
549VOID\r
550CVfrVarDataTypeDB::RegisterNewType (\r
551 IN SVfrDataType *New\r
552 )\r
553{\r
554 New->mNext = mDataTypeList;\r
555 mDataTypeList = New;\r
556}\r
557\r
558EFI_VFR_RETURN_CODE\r
559CVfrVarDataTypeDB::ExtractStructTypeName (\r
560 IN CHAR8 *&VarStr,\r
561 OUT CHAR8 *TName\r
562 )\r
563{\r
564 if (TName == NULL) {\r
565 return VFR_RETURN_FATAL_ERROR;\r
566 }\r
567\r
568 while((*VarStr != '\0') && (*VarStr != '.')) {\r
569 *TName = *VarStr;\r
570 VarStr++;\r
571 TName++;\r
572 }\r
573 *TName = '\0';\r
574 if (*VarStr == '.') {\r
575 VarStr++;\r
576 }\r
577\r
578 return VFR_RETURN_SUCCESS;\r
579}\r
580\r
581EFI_VFR_RETURN_CODE\r
582CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
583 IN CHAR8 *&VarStr,\r
584 IN CHAR8 *FName,\r
585 OUT UINT32 &ArrayIdx\r
586 )\r
587{\r
588 UINT32 Idx;\r
589 CHAR8 ArrayStr[MAX_NAME_LEN + 1];\r
590\r
591 ArrayIdx = INVALID_ARRAY_INDEX;\r
592\r
593 if (FName == NULL) {\r
594 return VFR_RETURN_FATAL_ERROR;\r
595 }\r
596\r
597 while((*VarStr != '\0') &&\r
598 (*VarStr != '.') &&\r
599 (*VarStr != '[') &&\r
600 (*VarStr != ']')) {\r
601 *FName = *VarStr;\r
602 VarStr++;\r
603 FName++;\r
604 }\r
605 *FName = '\0';\r
606\r
607 switch (*VarStr) {\r
608 case '.' :\r
609 VarStr++;\r
610 case '\0':\r
611 return VFR_RETURN_SUCCESS;\r
612 case '[' :\r
613 VarStr++;\r
614 for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {\r
615 ArrayStr[Idx] = *VarStr;\r
616 }\r
617 ArrayStr[Idx] = '\0';\r
618\r
619 if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {\r
620 return VFR_RETURN_DATA_STRING_ERROR;\r
621 }\r
622 ArrayIdx = _STR2U32 (ArrayStr);\r
623 if (*VarStr == ']') {\r
624 VarStr++;\r
625 }\r
626 if (*VarStr == '.') {\r
627 VarStr++;\r
628 }\r
629 return VFR_RETURN_SUCCESS;\r
630 case ']':\r
631 return VFR_RETURN_DATA_STRING_ERROR;\r
632 }\r
633\r
634 return VFR_RETURN_SUCCESS;\r
635}\r
636\r
637EFI_VFR_RETURN_CODE\r
638CVfrVarDataTypeDB::GetTypeField (\r
639 IN CONST CHAR8 *FName,\r
640 IN SVfrDataType *Type,\r
641 OUT SVfrDataField *&Field\r
642 )\r
643{\r
644 SVfrDataField *pField = NULL;\r
645\r
646 if ((FName == NULL) && (Type == NULL)) {\r
647 return VFR_RETURN_FATAL_ERROR;\r
648 }\r
649\r
650 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
651 //\r
652 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,\r
653 // add code to adjust it.\r
654 //\r
655 if (Type->mType == EFI_IFR_TYPE_TIME) {\r
656 if (strcmp (FName, "Hour") == 0) {\r
657 FName = "Hours";\r
658 } else if (strcmp (FName, "Minute") == 0) {\r
659 FName = "Minuts";\r
660 } else if (strcmp (FName, "Second") == 0) {\r
661 FName = "Seconds";\r
662 }\r
663 }\r
664\r
665 if (strcmp (pField->mFieldName, FName) == 0) {\r
666 Field = pField;\r
667 return VFR_RETURN_SUCCESS;\r
668 }\r
669 }\r
670\r
671 return VFR_RETURN_UNDEFINED;\r
672}\r
673\r
674EFI_VFR_RETURN_CODE\r
675CVfrVarDataTypeDB::GetFieldOffset (\r
676 IN SVfrDataField *Field,\r
677 IN UINT32 ArrayIdx,\r
678 OUT UINT32 &Offset\r
679 )\r
680{\r
681 if (Field == NULL) {\r
682 return VFR_RETURN_FATAL_ERROR;\r
683 }\r
684 \r
685 //\r
686 // Framework Vfr file Array Index is from 1.\r
687 // But Uefi Vfr file Array Index is from 0.\r
688 //\r
689 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {\r
690 if (ArrayIdx == 0) {\r
691 return VFR_RETURN_ERROR_ARRARY_NUM;\r
692 }\r
693 ArrayIdx = ArrayIdx - 1;\r
694 }\r
695\r
696 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
697 return VFR_RETURN_ERROR_ARRARY_NUM;\r
698 }\r
699 \r
700 //\r
701 // Be compatible with the current usage\r
702 // If ArraryIdx is not specified, the first one is used.\r
703 //\r
704 // if ArrayNum is larger than zero, ArraryIdx must be specified.\r
705 //\r
706 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {\r
707 // return VFR_RETURN_ERROR_ARRARY_NUM;\r
708 // }\r
709 //\r
710\r
711 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
712 return VFR_RETURN_SUCCESS;\r
713}\r
714\r
715UINT8\r
716CVfrVarDataTypeDB::GetFieldWidth (\r
717 IN SVfrDataField *Field\r
718 )\r
719{\r
720 if (Field == NULL) {\r
721 return 0;\r
722 }\r
723\r
724 return Field->mFieldType->mType;\r
725}\r
726\r
727UINT32\r
728CVfrVarDataTypeDB::GetFieldSize (\r
729 IN SVfrDataField *Field,\r
730 IN UINT32 ArrayIdx\r
731 )\r
732{\r
733 if (Field == NULL) {\r
734 return VFR_RETURN_FATAL_ERROR;\r
735 }\r
736\r
737 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
738 return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
739 } else {\r
740 return Field->mFieldType->mTotalSize;\r
741 }\r
742}\r
743\r
744VOID\r
745CVfrVarDataTypeDB::InternalTypesListInit (\r
746 VOID\r
747 )\r
748{\r
749 SVfrDataType *New = NULL;\r
750 UINT32 Index;\r
751\r
752 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
753 New = new SVfrDataType;\r
754 if (New != NULL) {\r
755 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
756 New->mType = gInternalTypesTable[Index].mType;\r
757 New->mAlign = gInternalTypesTable[Index].mAlign;\r
758 New->mTotalSize = gInternalTypesTable[Index].mSize;\r
759 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {\r
760 SVfrDataField *pYearField = new SVfrDataField;\r
761 SVfrDataField *pMonthField = new SVfrDataField;\r
762 SVfrDataField *pDayField = new SVfrDataField;\r
763\r
764 strcpy (pYearField->mFieldName, "Year");\r
765 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);\r
766 pYearField->mOffset = 0;\r
767 pYearField->mNext = pMonthField;\r
768 pYearField->mArrayNum = 0;\r
769\r
770 strcpy (pMonthField->mFieldName, "Month");\r
771 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);\r
772 pMonthField->mOffset = 2;\r
773 pMonthField->mNext = pDayField;\r
774 pMonthField->mArrayNum = 0;\r
775\r
776 strcpy (pDayField->mFieldName, "Day");\r
777 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);\r
778 pDayField->mOffset = 3;\r
779 pDayField->mNext = NULL;\r
780 pDayField->mArrayNum = 0;\r
781\r
782 New->mMembers = pYearField;\r
783 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
784 SVfrDataField *pHoursField = new SVfrDataField;\r
785 SVfrDataField *pMinutesField = new SVfrDataField;\r
786 SVfrDataField *pSecondsField = new SVfrDataField;\r
787\r
788 strcpy (pHoursField->mFieldName, "Hours");\r
789 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);\r
790 pHoursField->mOffset = 0;\r
791 pHoursField->mNext = pMinutesField;\r
792 pHoursField->mArrayNum = 0;\r
793\r
794 strcpy (pMinutesField->mFieldName, "Minutes");\r
795 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);\r
796 pMinutesField->mOffset = 1;\r
797 pMinutesField->mNext = pSecondsField;\r
798 pMinutesField->mArrayNum = 0;\r
799\r
800 strcpy (pSecondsField->mFieldName, "Seconds");\r
801 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);\r
802 pSecondsField->mOffset = 2;\r
803 pSecondsField->mNext = NULL;\r
804 pSecondsField->mArrayNum = 0;\r
805\r
806 New->mMembers = pHoursField;\r
807 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {\r
808 SVfrDataField *pQuestionIdField = new SVfrDataField;\r
809 SVfrDataField *pFormIdField = new SVfrDataField;\r
810 SVfrDataField *pFormSetGuidField = new SVfrDataField;\r
811 SVfrDataField *pDevicePathField = new SVfrDataField;\r
812\r
813 strcpy (pQuestionIdField->mFieldName, "QuestionId");\r
814 GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);\r
815 pQuestionIdField->mOffset = 0;\r
816 pQuestionIdField->mNext = pFormIdField;\r
817 pQuestionIdField->mArrayNum = 0;\r
818\r
819 strcpy (pFormIdField->mFieldName, "FormId");\r
820 GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);\r
821 pFormIdField->mOffset = 2;\r
822 pFormIdField->mNext = pFormSetGuidField;\r
823 pFormIdField->mArrayNum = 0;\r
824\r
825 strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");\r
826 GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);\r
827 pFormSetGuidField->mOffset = 4;\r
828 pFormSetGuidField->mNext = pDevicePathField;\r
829 pFormSetGuidField->mArrayNum = 0;\r
830\r
831 strcpy (pDevicePathField->mFieldName, "DevicePath");\r
832 GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);\r
833 pDevicePathField->mOffset = 20;\r
834 pDevicePathField->mNext = NULL;\r
835 pDevicePathField->mArrayNum = 0;\r
836\r
837 New->mMembers = pQuestionIdField;\r
838 } else {\r
839 New->mMembers = NULL;\r
840 }\r
841 New->mNext = NULL;\r
842 RegisterNewType (New);\r
843 New = NULL;\r
844 }\r
845 }\r
846}\r
847\r
848CVfrVarDataTypeDB::CVfrVarDataTypeDB (\r
849 VOID\r
850 )\r
851{\r
852 mDataTypeList = NULL;\r
853 mNewDataType = NULL;\r
854 mCurrDataField = NULL;\r
855 mPackAlign = DEFAULT_PACK_ALIGN;\r
856 mPackStack = NULL;\r
857 mFirstNewDataTypeName = NULL;\r
858\r
859 InternalTypesListInit ();\r
860}\r
861\r
862CVfrVarDataTypeDB::~CVfrVarDataTypeDB (\r
863 VOID\r
864 )\r
865{\r
866 SVfrDataType *pType;\r
867 SVfrDataField *pField;\r
868 SVfrPackStackNode *pPack;\r
869\r
870 if (mNewDataType != NULL) {\r
871 delete mNewDataType;\r
872 }\r
873\r
874 while (mDataTypeList != NULL) {\r
875 pType = mDataTypeList;\r
876 mDataTypeList = mDataTypeList->mNext;\r
877 while(pType->mMembers != NULL) {\r
878 pField = pType->mMembers;\r
879 pType->mMembers = pType->mMembers->mNext;\r
880 delete pField;\r
881 }\r
882 delete pType;\r
883 }\r
884\r
885 while (mPackStack != NULL) {\r
886 pPack = mPackStack;\r
887 mPackStack = mPackStack->mNext;\r
888 delete pPack;\r
889 }\r
890}\r
891\r
892EFI_VFR_RETURN_CODE\r
893CVfrVarDataTypeDB::Pack (\r
894 IN UINT32 LineNum,\r
895 IN UINT8 Action,\r
896 IN CHAR8 *Identifier,\r
897 IN UINT32 Number\r
898 )\r
899{\r
900 UINT32 PackAlign;\r
901 CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
902\r
903 if (Action & VFR_PACK_SHOW) {\r
904 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
905 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);\r
906 }\r
907\r
908 if (Action & VFR_PACK_PUSH) {\r
909 SVfrPackStackNode *pNew = NULL;\r
910\r
911 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {\r
912 return VFR_RETURN_FATAL_ERROR;\r
913 }\r
914 pNew->mNext = mPackStack;\r
915 mPackStack = pNew;\r
916 }\r
917\r
918 if (Action & VFR_PACK_POP) {\r
919 SVfrPackStackNode *pNode = NULL;\r
920\r
921 if (mPackStack == NULL) {\r
922 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");\r
923 }\r
924\r
925 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
926 if (pNode->Match (Identifier) == TRUE) {\r
927 mPackAlign = pNode->mNumber;\r
928 mPackStack = pNode->mNext;\r
929 }\r
930 }\r
931 }\r
932\r
933 if (Action & VFR_PACK_ASSIGN) {\r
934 PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
935 if ((PackAlign == 0) || (PackAlign > 16)) {\r
936 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
937 } else {\r
938 mPackAlign = PackAlign;\r
939 }\r
940 }\r
941\r
942 return VFR_RETURN_SUCCESS;\r
943}\r
944\r
945VOID\r
946CVfrVarDataTypeDB::DeclareDataTypeBegin (\r
947 VOID\r
948 )\r
949{\r
950 SVfrDataType *pNewType = NULL;\r
951\r
952 pNewType = new SVfrDataType;\r
953 pNewType->mTypeName[0] = '\0';\r
954 pNewType->mType = EFI_IFR_TYPE_OTHER;\r
955 pNewType->mAlign = DEFAULT_ALIGN;\r
956 pNewType->mTotalSize = 0;\r
957 pNewType->mMembers = NULL;\r
958 pNewType->mNext = NULL;\r
959\r
960 mNewDataType = pNewType;\r
961}\r
962\r
963EFI_VFR_RETURN_CODE\r
964CVfrVarDataTypeDB::SetNewTypeName (\r
965 IN CHAR8 *TypeName\r
966 )\r
967{\r
968 SVfrDataType *pType;\r
969\r
970 if (mNewDataType == NULL) {\r
971 return VFR_RETURN_ERROR_SKIPED;\r
972 }\r
973 if (TypeName == NULL) {\r
974 return VFR_RETURN_FATAL_ERROR;\r
975 }\r
976 if (strlen(TypeName) >= MAX_NAME_LEN) {\r
977 return VFR_RETURN_INVALID_PARAMETER;\r
978 }\r
979\r
980 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
981 if (strcmp(pType->mTypeName, TypeName) == 0) {\r
982 return VFR_RETURN_REDEFINED;\r
983 }\r
984 }\r
985\r
986 strcpy(mNewDataType->mTypeName, TypeName);\r
987 return VFR_RETURN_SUCCESS;\r
988}\r
989\r
990EFI_VFR_RETURN_CODE\r
991CVfrVarDataTypeDB::DataTypeAddField (\r
992 IN CHAR8 *FieldName,\r
993 IN CHAR8 *TypeName,\r
994 IN UINT32 ArrayNum\r
995 )\r
996{\r
997 SVfrDataField *pNewField = NULL;\r
998 SVfrDataType *pFieldType = NULL;\r
999 SVfrDataField *pTmp;\r
1000 UINT32 Align;\r
1001\r
1002 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
1003\r
1004 if (strlen (FieldName) >= MAX_NAME_LEN) {\r
1005 return VFR_RETURN_INVALID_PARAMETER;\r
1006 }\r
1007\r
1008 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
1009 if (strcmp (pTmp->mFieldName, FieldName) == 0) {\r
1010 return VFR_RETURN_REDEFINED;\r
1011 }\r
1012 }\r
1013\r
1014 Align = MIN (mPackAlign, pFieldType->mAlign);\r
1015\r
1016 if ((pNewField = new SVfrDataField) == NULL) {\r
1017 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1018 }\r
1019 strcpy (pNewField->mFieldName, FieldName);\r
1020 pNewField->mFieldType = pFieldType;\r
1021 pNewField->mArrayNum = ArrayNum;\r
1022 if ((mNewDataType->mTotalSize % Align) == 0) {\r
1023 pNewField->mOffset = mNewDataType->mTotalSize;\r
1024 } else {\r
1025 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
1026 }\r
1027 if (mNewDataType->mMembers == NULL) {\r
1028 mNewDataType->mMembers = pNewField;\r
1029 pNewField->mNext = NULL;\r
1030 } else {\r
1031 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
1032 ;\r
1033 pTmp->mNext = pNewField;\r
1034 pNewField->mNext = NULL;\r
1035 }\r
1036\r
1037 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
1038 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
1039\r
1040 return VFR_RETURN_SUCCESS;\r
1041}\r
1042\r
1043VOID\r
1044CVfrVarDataTypeDB::DeclareDataTypeEnd (\r
1045 VOID\r
1046 )\r
1047{\r
1048 if (mNewDataType->mTypeName[0] == '\0') {\r
1049 return;\r
1050 }\r
1051\r
1052 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {\r
1053 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);\r
1054 }\r
1055\r
1056 RegisterNewType (mNewDataType);\r
1057 if (mFirstNewDataTypeName == NULL) {\r
1058 mFirstNewDataTypeName = mNewDataType->mTypeName;\r
1059 }\r
1060\r
1061 mNewDataType = NULL;\r
1062}\r
1063\r
1064EFI_VFR_RETURN_CODE\r
1065CVfrVarDataTypeDB::GetDataType (\r
1066 IN CHAR8 *TypeName,\r
1067 OUT SVfrDataType **DataType\r
1068 )\r
1069{\r
1070 SVfrDataType *pDataType = NULL;\r
1071\r
1072 if (TypeName == NULL) {\r
1073 return VFR_RETURN_ERROR_SKIPED;\r
1074 }\r
1075\r
1076 if (DataType == NULL) {\r
1077 return VFR_RETURN_FATAL_ERROR;\r
1078 }\r
1079\r
1080 *DataType = NULL;\r
1081\r
1082 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1083 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1084 *DataType = pDataType;\r
1085 return VFR_RETURN_SUCCESS;\r
1086 }\r
1087 }\r
1088\r
1089 return VFR_RETURN_UNDEFINED;\r
1090}\r
1091\r
1092EFI_VFR_RETURN_CODE\r
1093CVfrVarDataTypeDB::GetDataTypeSize (\r
1094 IN UINT8 DataType,\r
1095 OUT UINT32 *Size\r
1096 )\r
1097{\r
1098 SVfrDataType *pDataType = NULL;\r
1099\r
1100 if (Size == NULL) {\r
1101 return VFR_RETURN_FATAL_ERROR;\r
1102 }\r
1103\r
1104 *Size = 0;\r
1105 DataType = DataType & 0x0F;\r
1106\r
1107 //\r
1108 // For user defined data type, the size can't be got by this function.\r
1109 //\r
1110 if (DataType == EFI_IFR_TYPE_OTHER) {\r
1111 return VFR_RETURN_SUCCESS;\r
1112 }\r
1113\r
1114 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1115 if (DataType == pDataType->mType) {\r
1116 *Size = pDataType->mTotalSize;\r
1117 return VFR_RETURN_SUCCESS;\r
1118 }\r
1119 }\r
1120\r
1121 return VFR_RETURN_UNDEFINED;\r
1122}\r
1123\r
1124EFI_VFR_RETURN_CODE\r
1125CVfrVarDataTypeDB::GetDataTypeSize (\r
1126 IN CHAR8 *TypeName,\r
1127 OUT UINT32 *Size\r
1128 )\r
1129{\r
1130 SVfrDataType *pDataType = NULL;\r
1131\r
1132 if (Size == NULL) {\r
1133 return VFR_RETURN_FATAL_ERROR;\r
1134 }\r
1135\r
1136 *Size = 0;\r
1137\r
1138 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1139 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1140 *Size = pDataType->mTotalSize;\r
1141 return VFR_RETURN_SUCCESS;\r
1142 }\r
1143 }\r
1144\r
1145 return VFR_RETURN_UNDEFINED;\r
1146}\r
1147\r
1148EFI_VFR_RETURN_CODE\r
1149CVfrVarDataTypeDB::GetDataFieldInfo (\r
1150 IN CHAR8 *VarStr,\r
1151 OUT UINT16 &Offset,\r
1152 OUT UINT8 &Type,\r
1153 OUT UINT32 &Size\r
1154 )\r
1155{\r
1156 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
1157 UINT32 ArrayIdx, Tmp;\r
1158 SVfrDataType *pType = NULL;\r
1159 SVfrDataField *pField = NULL;\r
1160\r
1161 Offset = 0;\r
1162 Type = EFI_IFR_TYPE_OTHER;\r
1163 Size = 0;\r
1164\r
1165 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
1166 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
1167\r
1168 //\r
1169 // if it is not struct data type\r
1170 //\r
1171 Type = pType->mType;\r
1172 Size = pType->mTotalSize;\r
1173\r
1174 while (*VarStr != '\0') {\r
1175 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
1176 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
1177 pType = pField->mFieldType;\r
1178 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
1179 Offset = (UINT16) (Offset + Tmp);\r
1180 Type = GetFieldWidth (pField);\r
1181 Size = GetFieldSize (pField, ArrayIdx);\r
1182 }\r
1183 return VFR_RETURN_SUCCESS;\r
1184}\r
1185\r
1186EFI_VFR_RETURN_CODE\r
1187CVfrVarDataTypeDB::GetUserDefinedTypeNameList (\r
1188 OUT CHAR8 ***NameList,\r
1189 OUT UINT32 *ListSize\r
1190 )\r
1191{\r
1192 UINT32 Index;\r
1193 SVfrDataType *pType;\r
1194\r
1195 if ((NameList == NULL) || (ListSize == NULL)) {\r
1196 return VFR_RETURN_FATAL_ERROR;\r
1197 }\r
1198\r
1199 *NameList = NULL;\r
1200 *ListSize = 0;\r
1201\r
1202 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1203 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1204 (*ListSize)++;\r
1205 }\r
1206 }\r
1207\r
1208 if (*ListSize == 0) {\r
1209 return VFR_RETURN_SUCCESS;\r
1210 }\r
1211\r
1212 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {\r
1213 *ListSize = 0;\r
1214 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1215 }\r
1216\r
1217 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {\r
1218 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1219 (*NameList)[Index] = pType->mTypeName;\r
1220 }\r
1221 }\r
1222 return VFR_RETURN_SUCCESS;\r
1223}\r
1224\r
1225BOOLEAN\r
1226CVfrVarDataTypeDB::IsTypeNameDefined (\r
1227 IN CHAR8 *TypeName\r
1228 )\r
1229{\r
1230 SVfrDataType *pType;\r
1231\r
1232 if (TypeName == NULL) {\r
1233 return FALSE;\r
1234 }\r
1235\r
1236 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1237 if (strcmp (pType->mTypeName, TypeName) == 0) {\r
1238 return TRUE;\r
1239 }\r
1240 }\r
1241\r
1242 return FALSE;\r
1243}\r
1244\r
1245VOID\r
1246CVfrVarDataTypeDB::Dump (\r
1247 IN FILE *File\r
1248 )\r
1249{\r
1250 SVfrDataType *pTNode;\r
1251 SVfrDataField *pFNode;\r
1252\r
1253 fprintf (File, "\n\n***************************************************************\n");\r
1254 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);\r
1255 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1256 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1257 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);\r
1258 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1259 if (pFNode->mArrayNum > 0) {\r
1260 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1261 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);\r
1262 } else {\r
1263 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1264 pFNode->mFieldName, pFNode->mFieldType->mTypeName);\r
1265 }\r
1266 }\r
1267 fprintf (File, "\t\t};\n");\r
1268 fprintf (File, "---------------------------------------------------------------\n");\r
1269 }\r
1270 fprintf (File, "***************************************************************\n");\r
1271}\r
1272\r
1273#ifdef CVFR_VARDATATYPEDB_DEBUG\r
1274VOID\r
1275CVfrVarDataTypeDB::ParserDB (\r
1276 VOID\r
1277 )\r
1278{\r
1279 SVfrDataType *pTNode;\r
1280 SVfrDataField *pFNode;\r
1281\r
1282 printf ("***************************************************************\n");\r
1283 printf ("\t\tmPackAlign = %x\n", mPackAlign);\r
1284 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1285 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1286 printf ("\t\tstruct %s {\n", pTNode->mTypeName);\r
1287 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1288 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
1289 }\r
1290 printf ("\t\t};\n");\r
1291 printf ("---------------------------------------------------------------\n");\r
1292 }\r
1293 printf ("***************************************************************\n");\r
1294}\r
1295#endif\r
1296\r
1297SVfrVarStorageNode::SVfrVarStorageNode (\r
1298 IN EFI_GUID *Guid,\r
1299 IN CHAR8 *StoreName,\r
1300 IN EFI_VARSTORE_ID VarStoreId,\r
1301 IN EFI_STRING_ID VarName,\r
1302 IN UINT32 VarSize,\r
1303 IN BOOLEAN Flag\r
1304 )\r
1305{\r
1306 if (Guid != NULL) {\r
1307 mGuid = *Guid;\r
1308 } else {\r
1309 memset (&Guid, 0, sizeof (EFI_GUID));\r
1310 }\r
1311 if (StoreName != NULL) {\r
1312 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1313 strcpy (mVarStoreName, StoreName);\r
1314 } else {\r
1315 mVarStoreName = NULL;\r
1316 }\r
1317 mNext = NULL;\r
1318 mVarStoreId = VarStoreId;\r
1319 mVarStoreType = EFI_VFR_VARSTORE_EFI;\r
1320 mStorageInfo.mEfiVar.mEfiVarName = VarName;\r
1321 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;\r
1322 mAssignedFlag = Flag;\r
1323}\r
1324\r
1325SVfrVarStorageNode::SVfrVarStorageNode (\r
1326 IN EFI_GUID *Guid,\r
1327 IN CHAR8 *StoreName,\r
1328 IN EFI_VARSTORE_ID VarStoreId,\r
1329 IN SVfrDataType *DataType,\r
1330 IN BOOLEAN Flag\r
1331 )\r
1332{\r
1333 if (Guid != NULL) {\r
1334 mGuid = *Guid;\r
1335 } else {\r
1336 memset (&Guid, 0, sizeof (EFI_GUID));\r
1337 }\r
1338 if (StoreName != NULL) {\r
1339 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1340 strcpy (mVarStoreName, StoreName);\r
1341 } else {\r
1342 mVarStoreName = NULL;\r
1343 }\r
1344 mNext = NULL;\r
1345 mVarStoreId = VarStoreId;\r
1346 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
1347 mStorageInfo.mDataType = DataType;\r
1348 mAssignedFlag = Flag;\r
1349}\r
1350\r
1351SVfrVarStorageNode::SVfrVarStorageNode (\r
1352 IN CHAR8 *StoreName,\r
1353 IN EFI_VARSTORE_ID VarStoreId\r
1354 )\r
1355{\r
1356 if (StoreName != NULL) {\r
1357 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1358 strcpy (mVarStoreName, StoreName);\r
1359 } else {\r
1360 mVarStoreName = NULL;\r
1361 }\r
1362 mNext = NULL;\r
1363 mVarStoreId = VarStoreId;\r
1364 mVarStoreType = EFI_VFR_VARSTORE_NAME;\r
1365 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
1366 mStorageInfo.mNameSpace.mTableSize = 0;\r
1367}\r
1368\r
1369SVfrVarStorageNode::~SVfrVarStorageNode (\r
1370 VOID\r
1371 )\r
1372{\r
1373 if (mVarStoreName != NULL) {\r
1374 delete mVarStoreName;\r
1375 }\r
1376\r
1377 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
1378 delete mStorageInfo.mNameSpace.mNameTable;\r
1379 }\r
1380}\r
1381\r
1382CVfrDataStorage::CVfrDataStorage (\r
1383 VOID\r
1384 )\r
1385{\r
1386 UINT32 Index;\r
1387\r
1388 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1389 mFreeVarStoreIdBitMap[Index] = 0;\r
1390 }\r
1391\r
1392 // Question ID 0 is reserved.\r
1393 mFreeVarStoreIdBitMap[0] = 0x80000000;\r
1394\r
1395 mBufferVarStoreList = NULL;\r
1396 mEfiVarStoreList = NULL;\r
1397 mNameVarStoreList = NULL;\r
1398 mCurrVarStorageNode = NULL;\r
1399 mNewVarStorageNode = NULL;\r
1400}\r
1401\r
1402CVfrDataStorage::~CVfrDataStorage (\r
1403 VOID\r
1404 )\r
1405{\r
1406 SVfrVarStorageNode *pNode;\r
1407\r
1408 while (mBufferVarStoreList != NULL) {\r
1409 pNode = mBufferVarStoreList;\r
1410 mBufferVarStoreList = mBufferVarStoreList->mNext;\r
1411 delete pNode;\r
1412 }\r
1413 while (mEfiVarStoreList != NULL) {\r
1414 pNode = mEfiVarStoreList;\r
1415 mEfiVarStoreList = mEfiVarStoreList->mNext;\r
1416 delete pNode;\r
1417 }\r
1418 while (mNameVarStoreList != NULL) {\r
1419 pNode = mNameVarStoreList;\r
1420 mNameVarStoreList = mNameVarStoreList->mNext;\r
1421 delete pNode;\r
1422 }\r
1423 if (mNewVarStorageNode != NULL) {\r
1424 delete mNewVarStorageNode;\r
1425 }\r
1426}\r
1427\r
1428EFI_VARSTORE_ID\r
1429CVfrDataStorage::GetFreeVarStoreId (\r
1430 EFI_VFR_VARSTORE_TYPE VarType\r
1431 )\r
1432{\r
1433 UINT32 Index, Mask, Offset;\r
1434 \r
1435 //\r
1436 // Assign the different ID range for the different type VarStore to support Framework Vfr\r
1437 //\r
1438 Index = 0;\r
1439 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {\r
1440 Index = 0;\r
1441 } else if (VarType == EFI_VFR_VARSTORE_EFI) {\r
1442 Index = 1;\r
1443 } else if (VarType == EFI_VFR_VARSTORE_NAME) {\r
1444 Index = 2;\r
1445 }\r
1446\r
1447 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1448 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {\r
1449 break;\r
1450 }\r
1451 }\r
1452\r
1453 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
1454 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
1455 mFreeVarStoreIdBitMap[Index] |= Mask;\r
1456 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
1457 }\r
1458 }\r
1459\r
1460 return EFI_VARSTORE_ID_INVALID;\r
1461}\r
1462\r
1463BOOLEAN\r
1464CVfrDataStorage::ChekVarStoreIdFree (\r
1465 IN EFI_VARSTORE_ID VarStoreId\r
1466 )\r
1467{\r
1468 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1469 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1470\r
1471 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
1472}\r
1473\r
1474VOID\r
1475CVfrDataStorage::MarkVarStoreIdUsed (\r
1476 IN EFI_VARSTORE_ID VarStoreId\r
1477 )\r
1478{\r
1479 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1480 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1481\r
1482 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
1483}\r
1484\r
1485VOID\r
1486CVfrDataStorage::MarkVarStoreIdUnused (\r
1487 IN EFI_VARSTORE_ID VarStoreId\r
1488 )\r
1489{\r
1490 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1491 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1492\r
1493 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
1494}\r
1495\r
1496EFI_VFR_RETURN_CODE\r
1497CVfrDataStorage::DeclareNameVarStoreBegin (\r
1498 IN CHAR8 *StoreName\r
1499 )\r
1500{\r
1501 SVfrVarStorageNode *pNode = NULL;\r
1502 EFI_VARSTORE_ID VarStoreId;\r
1503\r
1504 if (StoreName == NULL) {\r
1505 return VFR_RETURN_FATAL_ERROR;\r
1506 }\r
1507\r
1508 if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
1509 return VFR_RETURN_REDEFINED;\r
1510 }\r
1511\r
1512 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
1513 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
1514 return VFR_RETURN_UNDEFINED;\r
1515 }\r
1516\r
1517 mNewVarStorageNode = pNode;\r
1518\r
1519 return VFR_RETURN_SUCCESS;\r
1520}\r
1521\r
1522EFI_VFR_RETURN_CODE\r
1523CVfrDataStorage::NameTableAddItem (\r
1524 IN EFI_STRING_ID Item\r
1525 )\r
1526{\r
1527 EFI_VARSTORE_ID *NewTable, *OldTable;\r
1528 UINT32 TableSize;\r
1529\r
1530 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
1531 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
1532\r
1533 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
1534 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
1535 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1536 }\r
1537 memcpy (NewTable, OldTable, TableSize);\r
1538 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
1539 }\r
1540\r
1541 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
1542 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
1543\r
1544 return VFR_RETURN_SUCCESS;\r
1545}\r
1546\r
1547EFI_VFR_RETURN_CODE\r
1548CVfrDataStorage::DeclareNameVarStoreEnd (\r
1549 IN EFI_GUID *Guid\r
1550 )\r
1551{\r
1552 mNewVarStorageNode->mGuid = *Guid;\r
1553 mNewVarStorageNode->mNext = mNameVarStoreList;\r
1554 mNameVarStoreList = mNewVarStorageNode;\r
1555\r
1556 mNewVarStorageNode = NULL;\r
1557\r
1558 return VFR_RETURN_SUCCESS;\r
1559}\r
1560\r
1561EFI_VFR_RETURN_CODE \r
1562CVfrDataStorage::DeclareEfiVarStore (\r
1563 IN CHAR8 *StoreName, \r
1564 IN EFI_GUID *Guid, \r
1565 IN EFI_STRING_ID NameStrId,\r
1566 IN UINT32 VarSize,\r
1567 IN BOOLEAN Flag\r
1568 )\r
1569{\r
1570 SVfrVarStorageNode *pNode;\r
1571 EFI_VARSTORE_ID VarStoreId;\r
1572\r
1573 if ((StoreName == NULL) || (Guid == NULL)) {\r
1574 return VFR_RETURN_FATAL_ERROR;\r
1575 }\r
1576\r
1577 if (VarSize > sizeof (UINT64)) {\r
1578 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
1579 }\r
1580\r
1581 if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
1582 return VFR_RETURN_REDEFINED;\r
1583 }\r
1584\r
1585 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
1586 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {\r
1587 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1588 }\r
1589\r
1590 pNode->mNext = mEfiVarStoreList;\r
1591 mEfiVarStoreList = pNode;\r
1592\r
1593 return VFR_RETURN_SUCCESS;\r
1594}\r
1595\r
1596EFI_VFR_RETURN_CODE \r
1597CVfrDataStorage::DeclareBufferVarStore (\r
1598 IN CHAR8 *StoreName, \r
1599 IN EFI_GUID *Guid, \r
1600 IN CVfrVarDataTypeDB *DataTypeDB,\r
1601 IN CHAR8 *TypeName,\r
1602 IN EFI_VARSTORE_ID VarStoreId,\r
1603 IN BOOLEAN Flag\r
1604 )\r
1605{\r
1606 SVfrVarStorageNode *pNew = NULL;\r
1607 SVfrDataType *pDataType = NULL;\r
1608 EFI_VARSTORE_ID TempVarStoreId;\r
1609\r
1610 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1611 return VFR_RETURN_FATAL_ERROR;\r
1612 }\r
1613\r
1614 if (GetVarStoreId (StoreName, &TempVarStoreId) == VFR_RETURN_SUCCESS) {\r
1615 return VFR_RETURN_REDEFINED;\r
1616 }\r
1617\r
1618 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
1619\r
1620 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1621 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);\r
1622 } else {\r
1623 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1624 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1625 }\r
1626 MarkVarStoreIdUsed (VarStoreId);\r
1627 }\r
1628\r
1629 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
1630 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1631 }\r
1632\r
1633 pNew->mNext = mBufferVarStoreList;\r
1634 mBufferVarStoreList = pNew;\r
1635\r
1636 if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
1637 return VFR_RETURN_FATAL_ERROR;\r
1638 }\r
1639\r
1640 return VFR_RETURN_SUCCESS;\r
1641}\r
1642\r
1643EFI_VFR_RETURN_CODE \r
1644CVfrDataStorage::GetVarStoreByDataType (\r
1645 IN CHAR8 *DataTypeName,\r
1646 OUT SVfrVarStorageNode **VarNode\r
1647 )\r
1648{\r
1649 SVfrVarStorageNode *pNode;\r
1650 SVfrVarStorageNode *MatchNode;\r
1651 \r
1652 //\r
1653 // Framework VFR uses Data type name as varstore name, so don't need check again.\r
1654 //\r
1655 if (VfrCompatibleMode) {\r
1656 return VFR_RETURN_UNDEFINED;\r
1657 }\r
1658\r
1659 MatchNode = NULL;\r
1660 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1661 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) == 0) {\r
1662 if (MatchNode == NULL) {\r
1663 MatchNode = pNode;\r
1664 } else {\r
1665 //\r
1666 // More than one varstores referred the same data structures.\r
1667 //\r
1668 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;\r
1669 }\r
1670 }\r
1671 }\r
1672 \r
1673 if (MatchNode == NULL) {\r
1674 return VFR_RETURN_UNDEFINED;\r
1675 }\r
1676\r
1677 *VarNode = MatchNode;\r
1678 return VFR_RETURN_SUCCESS;\r
1679}\r
1680\r
1681EFI_VFR_RETURN_CODE \r
1682CVfrDataStorage::GetVarStoreId (\r
1683 IN CHAR8 *StoreName,\r
1684 OUT EFI_VARSTORE_ID *VarStoreId\r
1685 )\r
1686{\r
1687 EFI_VFR_RETURN_CODE ReturnCode;\r
1688 SVfrVarStorageNode *pNode;\r
1689\r
1690 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1691 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1692 mCurrVarStorageNode = pNode;\r
1693 *VarStoreId = pNode->mVarStoreId;\r
1694 return VFR_RETURN_SUCCESS;\r
1695 }\r
1696 }\r
1697\r
1698 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1699 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1700 mCurrVarStorageNode = pNode;\r
1701 *VarStoreId = pNode->mVarStoreId;\r
1702 return VFR_RETURN_SUCCESS;\r
1703 }\r
1704 }\r
1705\r
1706 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1707 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1708 mCurrVarStorageNode = pNode;\r
1709 *VarStoreId = pNode->mVarStoreId;\r
1710 return VFR_RETURN_SUCCESS;\r
1711 }\r
1712 }\r
1713\r
1714 mCurrVarStorageNode = NULL;\r
1715 *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
1716\r
1717 //\r
1718 // Assume that Data strucutre name is used as StoreName, and check again. \r
1719 //\r
1720 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1721 if (pNode != NULL) {\r
1722 mCurrVarStorageNode = pNode;\r
1723 *VarStoreId = pNode->mVarStoreId;\r
1724 }\r
1725 \r
1726 return ReturnCode;\r
1727}\r
1728\r
1729EFI_VFR_RETURN_CODE\r
1730CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
1731 IN CHAR8 *StoreName,\r
1732 OUT CHAR8 **DataTypeName\r
1733 )\r
1734{\r
1735 SVfrVarStorageNode *pNode;\r
1736 EFI_VFR_RETURN_CODE ReturnCode;\r
1737\r
1738 if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
1739 return VFR_RETURN_FATAL_ERROR;\r
1740 }\r
1741\r
1742 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1743 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1744 break;\r
1745 }\r
1746 }\r
1747\r
1748 ReturnCode = VFR_RETURN_UNDEFINED;\r
1749 //\r
1750 // Assume that Data strucutre name is used as StoreName, and check again. \r
1751 //\r
1752 if (pNode == NULL) {\r
1753 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1754 }\r
1755\r
1756 if (pNode == NULL) {\r
1757 return ReturnCode;\r
1758 }\r
1759\r
1760 if (pNode->mStorageInfo.mDataType == NULL) {\r
1761 return VFR_RETURN_FATAL_ERROR;\r
1762 }\r
1763\r
1764 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
1765 return VFR_RETURN_SUCCESS;\r
1766}\r
1767\r
1768EFI_VFR_RETURN_CODE\r
1769CVfrDataStorage::GetVarStoreType (\r
1770 IN CHAR8 *StoreName,\r
1771 OUT EFI_VFR_VARSTORE_TYPE &VarStoreType\r
1772 )\r
1773{\r
1774 SVfrVarStorageNode *pNode;\r
1775 EFI_VFR_RETURN_CODE ReturnCode;\r
1776\r
1777 if (StoreName == NULL) {\r
1778 return VFR_RETURN_FATAL_ERROR;\r
1779 }\r
1780\r
1781 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1782 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1783 VarStoreType = pNode->mVarStoreType;\r
1784 return VFR_RETURN_SUCCESS;\r
1785 }\r
1786 }\r
1787\r
1788 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1789 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1790 VarStoreType = pNode->mVarStoreType;\r
1791 return VFR_RETURN_SUCCESS;\r
1792 }\r
1793 }\r
1794\r
1795 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1796 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1797 VarStoreType = pNode->mVarStoreType;\r
1798 return VFR_RETURN_SUCCESS;\r
1799 }\r
1800 }\r
1801\r
1802 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1803\r
1804 //\r
1805 // Assume that Data strucutre name is used as StoreName, and check again. \r
1806 //\r
1807 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1808 if (pNode != NULL) {\r
1809 VarStoreType = pNode->mVarStoreType;\r
1810 }\r
1811 \r
1812 return ReturnCode;\r
1813}\r
1814\r
1815EFI_VFR_VARSTORE_TYPE\r
1816CVfrDataStorage::GetVarStoreType (\r
1817 IN EFI_VARSTORE_ID VarStoreId\r
1818 )\r
1819{\r
1820 SVfrVarStorageNode *pNode;\r
1821 EFI_VFR_VARSTORE_TYPE VarStoreType;\r
1822\r
1823 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1824\r
1825 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1826 return VarStoreType;\r
1827 }\r
1828\r
1829 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1830 if (pNode->mVarStoreId == VarStoreId) {\r
1831 VarStoreType = pNode->mVarStoreType;\r
1832 return VarStoreType;\r
1833 }\r
1834 }\r
1835\r
1836 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1837 if (pNode->mVarStoreId == VarStoreId) {\r
1838 VarStoreType = pNode->mVarStoreType;\r
1839 return VarStoreType;\r
1840 }\r
1841 }\r
1842\r
1843 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1844 if (pNode->mVarStoreId == VarStoreId) {\r
1845 VarStoreType = pNode->mVarStoreType;\r
1846 return VarStoreType;\r
1847 }\r
1848 }\r
1849\r
1850 return VarStoreType;\r
1851}\r
1852\r
1853EFI_VFR_RETURN_CODE\r
1854CVfrDataStorage::GetVarStoreName (\r
1855 IN EFI_VARSTORE_ID VarStoreId, \r
1856 OUT CHAR8 **VarStoreName\r
1857 )\r
1858{\r
1859 SVfrVarStorageNode *pNode;\r
1860\r
1861 if (VarStoreName == NULL) {\r
1862 return VFR_RETURN_FATAL_ERROR;\r
1863 }\r
1864\r
1865 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1866 if (pNode->mVarStoreId == VarStoreId) {\r
1867 *VarStoreName = pNode->mVarStoreName;\r
1868 return VFR_RETURN_SUCCESS;\r
1869 }\r
1870 }\r
1871\r
1872 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1873 if (pNode->mVarStoreId == VarStoreId) {\r
1874 *VarStoreName = pNode->mVarStoreName;\r
1875 return VFR_RETURN_SUCCESS;\r
1876 }\r
1877 }\r
1878\r
1879 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1880 if (pNode->mVarStoreId == VarStoreId) {\r
1881 *VarStoreName = pNode->mVarStoreName;\r
1882 return VFR_RETURN_SUCCESS;\r
1883 }\r
1884 }\r
1885\r
1886 *VarStoreName = NULL;\r
1887 return VFR_RETURN_UNDEFINED;\r
1888}\r
1889\r
1890EFI_VFR_RETURN_CODE\r
1891CVfrDataStorage::GetEfiVarStoreInfo (\r
1892 IN OUT EFI_VARSTORE_INFO *Info\r
1893 )\r
1894{\r
1895 if (Info == NULL) {\r
1896 return VFR_RETURN_FATAL_ERROR;\r
1897 }\r
1898\r
1899 if (mCurrVarStorageNode == NULL) {\r
1900 return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
1901 }\r
1902\r
1903 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
1904 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
1905 switch (Info->mVarTotalSize) {\r
1906 case 1:\r
1907 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
1908 break;\r
1909 case 2:\r
1910 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
1911 break;\r
1912 case 4:\r
1913 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
1914 break;\r
1915 case 8:\r
1916 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
1917 break;\r
1918 default :\r
1919 return VFR_RETURN_FATAL_ERROR;\r
1920 }\r
1921\r
1922 return VFR_RETURN_SUCCESS;\r
1923}\r
1924\r
1925EFI_VFR_RETURN_CODE\r
1926CVfrDataStorage::GetNameVarStoreInfo (\r
1927 OUT EFI_VARSTORE_INFO *Info,\r
1928 IN UINT32 Index\r
1929 )\r
1930{\r
1931 if (Info == NULL) {\r
1932 return VFR_RETURN_FATAL_ERROR;\r
1933 }\r
1934\r
1935 if (mCurrVarStorageNode == NULL) {\r
1936 return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
1937 }\r
1938 \r
1939 //\r
1940 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
1941 //\r
1942 if (VfrCompatibleMode) {\r
1943 if (Index == 0) {\r
1944 return VFR_RETURN_ERROR_ARRARY_NUM;\r
1945 }\r
1946 Index --;\r
1947 }\r
1948\r
1949 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
1950\r
1951 return VFR_RETURN_SUCCESS;\r
1952}\r
1953\r
1954EFI_VFR_RETURN_CODE\r
1955CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
1956 IN CHAR8 *StoreName,\r
1957 IN EFI_VARSTORE_INFO &Info\r
1958 )\r
1959{\r
1960 SVfrVarStorageNode *pNode = NULL;\r
1961 EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;\r
1962 EFI_VFR_RETURN_CODE ReturnCode;\r
1963\r
1964 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1965 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1966 break;\r
1967 }\r
1968 }\r
1969\r
1970 ReturnCode = VFR_RETURN_UNDEFINED;\r
1971 //\r
1972 // Assume that Data strucutre name is used as StoreName, and check again. \r
1973 //\r
1974 if (pNode == NULL) {\r
1975 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1976 }\r
1977\r
1978 if (pNode == NULL) {\r
1979 return ReturnCode;\r
1980 }\r
1981\r
1982 gCVfrBufferConfig.Open ();\r
1983 Value.u8 = 0;\r
1984 if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
1985 return VFR_RETURN_FATAL_ERROR;\r
1986 }\r
1987 gCVfrBufferConfig.Close ();\r
1988\r
1989 return VFR_RETURN_SUCCESS;\r
1990}\r
1991\r
1992SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
1993 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
1994 IN CHAR8 *RefName, \r
1995 IN EFI_STRING_ID DefaultStoreNameId, \r
1996 IN UINT16 DefaultId\r
1997 )\r
1998{\r
1999 mObjBinAddr = ObjBinAddr;\r
2000\r
2001 if (RefName != NULL) {\r
2002 mRefName = new CHAR8[strlen (RefName) + 1];\r
2003 strcpy (mRefName, RefName);\r
2004 } else {\r
2005 mRefName = NULL;\r
2006 }\r
2007\r
2008 mNext = NULL;\r
2009 mDefaultId = DefaultId;\r
2010 mDefaultStoreNameId = DefaultStoreNameId;\r
2011}\r
2012\r
2013SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
2014 VOID\r
2015 )\r
2016{\r
2017 if (mRefName != NULL) {\r
2018 delete mRefName;\r
2019 }\r
2020}\r
2021\r
2022CVfrDefaultStore::CVfrDefaultStore (\r
2023 VOID\r
2024 )\r
2025{\r
2026 mDefaultStoreList = NULL;\r
2027}\r
2028\r
2029CVfrDefaultStore::~CVfrDefaultStore (\r
2030 VOID\r
2031 )\r
2032{\r
2033 SVfrDefaultStoreNode *pTmp = NULL;\r
2034\r
2035 while (mDefaultStoreList != NULL) {\r
2036 pTmp = mDefaultStoreList;\r
2037 mDefaultStoreList = mDefaultStoreList->mNext;\r
2038 delete pTmp;\r
2039 }\r
2040}\r
2041\r
2042EFI_VFR_RETURN_CODE\r
2043CVfrDefaultStore::RegisterDefaultStore (\r
2044 IN CHAR8 *ObjBinAddr,\r
2045 IN CHAR8 *RefName,\r
2046 IN EFI_STRING_ID DefaultStoreNameId,\r
2047 IN UINT16 DefaultId\r
2048 )\r
2049{\r
2050 SVfrDefaultStoreNode *pNode = NULL;\r
2051\r
2052 if (RefName == NULL) {\r
2053 return VFR_RETURN_FATAL_ERROR;\r
2054 }\r
2055\r
2056 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2057 if (strcmp (pNode->mRefName, RefName) == 0) {\r
2058 return VFR_RETURN_REDEFINED;\r
2059 }\r
2060 }\r
2061\r
2062 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
2063 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2064 }\r
2065\r
2066 pNode->mNext = mDefaultStoreList;\r
2067 mDefaultStoreList = pNode;\r
2068\r
2069 return VFR_RETURN_SUCCESS;\r
2070}\r
2071\r
2072/*\r
2073 * assign new reference name or new default store name id only if \r
2074 * the original is invalid\r
2075 */\r
2076EFI_VFR_RETURN_CODE\r
2077CVfrDefaultStore::ReRegisterDefaultStoreById (\r
2078 IN UINT16 DefaultId,\r
2079 IN CHAR8 *RefName,\r
2080 IN EFI_STRING_ID DefaultStoreNameId\r
2081 )\r
2082{\r
2083 SVfrDefaultStoreNode *pNode = NULL;\r
2084\r
2085 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2086 if (pNode->mDefaultId == DefaultId) {\r
2087 break;\r
2088 }\r
2089 }\r
2090\r
2091 if (pNode == NULL) {\r
2092 return VFR_RETURN_UNDEFINED;\r
2093 } else {\r
2094 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
2095 pNode->mDefaultStoreNameId = DefaultStoreNameId;\r
2096 if (pNode->mObjBinAddr != NULL) {\r
2097 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
2098 }\r
2099 } else {\r
2100 return VFR_RETURN_REDEFINED;\r
2101 }\r
2102\r
2103 if (RefName != NULL) {\r
2104 delete pNode->mRefName;\r
2105 pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
2106 if (pNode->mRefName != NULL) {\r
2107 strcpy (pNode->mRefName, RefName);\r
2108 }\r
2109 }\r
2110 }\r
2111\r
2112 return VFR_RETURN_SUCCESS;\r
2113}\r
2114\r
2115BOOLEAN\r
2116CVfrDefaultStore::DefaultIdRegistered (\r
2117 IN UINT16 DefaultId\r
2118 )\r
2119{\r
2120 SVfrDefaultStoreNode *pNode = NULL;\r
2121\r
2122 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2123 if (pNode->mDefaultId == DefaultId) {\r
2124 return TRUE;\r
2125 }\r
2126 }\r
2127\r
2128 return FALSE;\r
2129}\r
2130\r
2131EFI_VFR_RETURN_CODE\r
2132CVfrDefaultStore::GetDefaultId (\r
2133 IN CHAR8 *RefName,\r
2134 OUT UINT16 *DefaultId\r
2135 )\r
2136{\r
2137 SVfrDefaultStoreNode *pTmp = NULL;\r
2138\r
2139 if (DefaultId == NULL) {\r
2140 return VFR_RETURN_FATAL_ERROR;\r
2141 }\r
2142\r
2143 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
2144 if (strcmp (pTmp->mRefName, RefName) == 0) {\r
2145 *DefaultId = pTmp->mDefaultId;\r
2146 return VFR_RETURN_SUCCESS;\r
2147 }\r
2148 }\r
2149\r
2150 return VFR_RETURN_UNDEFINED;\r
2151}\r
2152\r
2153EFI_VFR_RETURN_CODE\r
2154CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2155 IN EFI_VARSTORE_ID DefaultId,\r
2156 IN EFI_VARSTORE_INFO &Info,\r
2157 IN CHAR8 *VarStoreName,\r
2158 IN UINT8 Type,\r
2159 IN EFI_IFR_TYPE_VALUE Value\r
2160 )\r
2161{\r
2162 SVfrDefaultStoreNode *pNode = NULL;\r
2163 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2164 INTN Returnvalue = 0;\r
2165\r
2166 if (VarStoreName == NULL) {\r
2167 return VFR_RETURN_FATAL_ERROR;\r
2168 }\r
2169\r
2170 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2171 if (pNode->mDefaultId == DefaultId) {\r
2172 break;\r
2173 }\r
2174 }\r
2175\r
2176 if (pNode == NULL) {\r
2177 return VFR_RETURN_UNDEFINED;\r
2178 }\r
2179\r
2180 gCVfrBufferConfig.Open ();\r
2181\r
2182 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
2183 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
2184 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
2185 goto WriteError;\r
2186 }\r
2187 }\r
2188 \r
2189 gCVfrBufferConfig.Close ();\r
2190\r
2191 return VFR_RETURN_SUCCESS;\r
2192\r
2193WriteError:\r
2194 gCVfrBufferConfig.Close ();\r
2195 return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2196}\r
2197\r
2198SVfrRuleNode::SVfrRuleNode (\r
2199 IN CHAR8 *RuleName,\r
2200 IN UINT8 RuleId\r
2201 )\r
2202{\r
2203 if (RuleName != NULL) {\r
2204 mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2205 strcpy (mRuleName, RuleName);\r
2206 } else {\r
2207 mRuleName = NULL;\r
2208 }\r
2209\r
2210 mNext = NULL;\r
2211 mRuleId = RuleId;\r
2212}\r
2213\r
2214SVfrRuleNode::~SVfrRuleNode (\r
2215 VOID\r
2216 )\r
2217{\r
2218 if (mRuleName != NULL) {\r
2219 delete mRuleName;\r
2220 }\r
2221}\r
2222\r
2223CVfrRulesDB::CVfrRulesDB ()\r
2224{\r
2225 mRuleList = NULL;\r
2226 mFreeRuleId = EFI_VARSTORE_ID_START;\r
2227}\r
2228\r
2229CVfrRulesDB::~CVfrRulesDB ()\r
2230{\r
2231 SVfrRuleNode *pNode;\r
2232\r
2233 while(mRuleList != NULL) {\r
2234 pNode = mRuleList;\r
2235 mRuleList = mRuleList->mNext;\r
2236 delete pNode;\r
2237 }\r
2238}\r
2239\r
2240VOID\r
2241CVfrRulesDB::RegisterRule (\r
2242 IN CHAR8 *RuleName\r
2243 )\r
2244{\r
2245 SVfrRuleNode *pNew;\r
2246\r
2247 if (RuleName == NULL) {\r
2248 return ;\r
2249 }\r
2250\r
2251 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2252 return ;\r
2253 }\r
2254\r
2255 mFreeRuleId++;\r
2256\r
2257 pNew->mNext = mRuleList;\r
2258 mRuleList = pNew;\r
2259}\r
2260\r
2261UINT8\r
2262CVfrRulesDB::GetRuleId (\r
2263 IN CHAR8 *RuleName\r
2264 )\r
2265{\r
2266 SVfrRuleNode *pNode;\r
2267\r
2268 if (RuleName == NULL) {\r
2269 return EFI_RULE_ID_INVALID;\r
2270 }\r
2271\r
2272 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2273 if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2274 return pNode->mRuleId;\r
2275 }\r
2276 }\r
2277\r
2278 return EFI_RULE_ID_INVALID;\r
2279}\r
2280\r
2281CVfrRulesDB gCVfrRulesDB;\r
2282\r
2283EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2284 VOID\r
2285 )\r
2286{\r
2287 mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2288 mInfo.mVarName = EFI_STRING_ID_INVALID;\r
2289 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2290 mVarType = EFI_IFR_TYPE_OTHER;\r
2291 mVarTotalSize = 0;\r
2292}\r
2293\r
2294EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2295 IN EFI_VARSTORE_INFO &Info\r
2296 )\r
2297{\r
2298 mVarStoreId = Info.mVarStoreId;\r
2299 mInfo.mVarName = Info.mInfo.mVarName;\r
2300 mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2301 mVarType = Info.mVarType;\r
2302 mVarTotalSize = Info.mVarTotalSize;\r
2303}\r
2304\r
2305BOOLEAN\r
2306EFI_VARSTORE_INFO::operator == (\r
2307 IN EFI_VARSTORE_INFO *Info\r
2308 )\r
2309{\r
2310 if ((mVarStoreId == Info->mVarStoreId) &&\r
2311 (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2312 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2313 (mVarType == Info->mVarType) &&\r
2314 (mVarTotalSize == Info->mVarTotalSize)) {\r
2315 return TRUE;\r
2316 }\r
2317\r
2318 return FALSE;\r
2319}\r
2320\r
2321static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2322\r
2323EFI_QUESTION_ID\r
2324CVfrQuestionDB::GetFreeQuestionId (\r
2325 VOID\r
2326 )\r
2327{\r
2328 UINT32 Index, Mask, Offset;\r
2329\r
2330 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2331 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2332 break;\r
2333 }\r
2334 }\r
2335\r
2336 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2337 if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2338 mFreeQIdBitMap[Index] |= Mask;\r
2339 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2340 }\r
2341 }\r
2342\r
2343 return EFI_QUESTION_ID_INVALID;\r
2344}\r
2345\r
2346BOOLEAN\r
2347CVfrQuestionDB::ChekQuestionIdFree (\r
2348 IN EFI_QUESTION_ID QId\r
2349 )\r
2350{\r
2351 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2352 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2353\r
2354 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2355}\r
2356\r
2357VOID\r
2358CVfrQuestionDB::MarkQuestionIdUsed (\r
2359 IN EFI_QUESTION_ID QId\r
2360 )\r
2361{\r
2362 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2363 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2364\r
2365 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2366}\r
2367\r
2368VOID\r
2369CVfrQuestionDB::MarkQuestionIdUnused (\r
2370 IN EFI_QUESTION_ID QId\r
2371 )\r
2372{\r
2373 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2374 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2375\r
2376 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2377}\r
2378\r
2379SVfrQuestionNode::SVfrQuestionNode (\r
2380 IN CHAR8 *Name,\r
2381 IN CHAR8 *VarIdStr,\r
2382 IN UINT32 BitMask\r
2383 )\r
2384{\r
2385 mName = NULL;\r
2386 mVarIdStr = NULL;\r
2387 mQuestionId = EFI_QUESTION_ID_INVALID;\r
2388 mBitMask = BitMask;\r
2389 mNext = NULL;\r
2390 mQtype = QUESTION_NORMAL;\r
2391\r
2392 if (Name == NULL) {\r
2393 mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2394 strcpy (mName, "$DEFAULT");\r
2395 } else {\r
2396 mName = new CHAR8[strlen (Name) + 1];\r
2397 strcpy (mName, Name);\r
2398 }\r
2399\r
2400 if (VarIdStr != NULL) {\r
2401 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2402 strcpy (mVarIdStr, VarIdStr);\r
2403 } else {\r
2404 mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2405 strcpy (mVarIdStr, "$");\r
2406 }\r
2407}\r
2408\r
2409SVfrQuestionNode::~SVfrQuestionNode (\r
2410 VOID\r
2411 )\r
2412{\r
2413 if (mName != NULL) {\r
2414 delete mName;\r
2415 }\r
2416\r
2417 if (mVarIdStr != NULL) {\r
2418 delete mVarIdStr;\r
2419 }\r
2420}\r
2421\r
2422CVfrQuestionDB::CVfrQuestionDB ()\r
2423{\r
2424 UINT32 Index;\r
2425\r
2426 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2427 mFreeQIdBitMap[Index] = 0;\r
2428 }\r
2429\r
2430 // Question ID 0 is reserved.\r
2431 mFreeQIdBitMap[0] = 0x80000000;\r
2432 mQuestionList = NULL;\r
2433}\r
2434\r
2435CVfrQuestionDB::~CVfrQuestionDB ()\r
2436{\r
2437 SVfrQuestionNode *pNode;\r
2438\r
2439 while (mQuestionList != NULL) {\r
2440 pNode = mQuestionList;\r
2441 mQuestionList = mQuestionList->mNext;\r
2442 delete pNode;\r
2443 }\r
2444}\r
2445\r
2446//\r
2447// Reset to init state\r
2448//\r
2449VOID\r
2450CVfrQuestionDB::ResetInit(\r
2451 IN VOID\r
2452 )\r
2453{\r
2454 UINT32 Index;\r
2455 SVfrQuestionNode *pNode;\r
2456\r
2457 while (mQuestionList != NULL) {\r
2458 pNode = mQuestionList;\r
2459 mQuestionList = mQuestionList->mNext;\r
2460 delete pNode;\r
2461 }\r
2462\r
2463 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2464 mFreeQIdBitMap[Index] = 0;\r
2465 }\r
2466\r
2467 // Question ID 0 is reserved.\r
2468 mFreeQIdBitMap[0] = 0x80000000;\r
2469 mQuestionList = NULL; \r
2470}\r
2471\r
2472VOID\r
2473CVfrQuestionDB::PrintAllQuestion (\r
2474 VOID\r
2475 )\r
2476{\r
2477 SVfrQuestionNode *pNode = NULL;\r
2478\r
2479 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2480 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2481 }\r
2482}\r
2483\r
2484EFI_VFR_RETURN_CODE\r
2485CVfrQuestionDB::RegisterQuestion (\r
2486 IN CHAR8 *Name,\r
2487 IN CHAR8 *VarIdStr,\r
2488 IN OUT EFI_QUESTION_ID &QuestionId\r
2489 )\r
2490{\r
2491 SVfrQuestionNode *pNode = NULL;\r
2492\r
2493 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2494 return VFR_RETURN_REDEFINED;\r
2495 }\r
2496\r
2497 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2498 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2499 }\r
2500\r
2501 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2502 QuestionId = GetFreeQuestionId ();\r
2503 } else {\r
2504 //\r
2505 // For Framework Vfr, don't check question ID conflict.\r
2506 //\r
2507 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2508 delete pNode;\r
2509 return VFR_RETURN_QUESTIONID_REDEFINED;\r
2510 }\r
2511 MarkQuestionIdUsed (QuestionId);\r
2512 }\r
2513 pNode->mQuestionId = QuestionId;\r
2514\r
2515 pNode->mNext = mQuestionList;\r
2516 mQuestionList = pNode;\r
2517\r
2518 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2519\r
2520 return VFR_RETURN_SUCCESS;\r
2521}\r
2522\r
2523VOID\r
2524CVfrQuestionDB::RegisterOldDateQuestion (\r
2525 IN CHAR8 *YearVarId,\r
2526 IN CHAR8 *MonthVarId,\r
2527 IN CHAR8 *DayVarId,\r
2528 IN OUT EFI_QUESTION_ID &QuestionId\r
2529 )\r
2530{\r
2531 SVfrQuestionNode *pNode[3] = {NULL, };\r
2532 UINT32 Index;\r
2533\r
2534 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2535 return;\r
2536 }\r
2537\r
2538 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2539 goto Err;\r
2540 }\r
2541 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2542 goto Err;\r
2543 }\r
2544 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2545 goto Err;\r
2546 }\r
2547\r
2548 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2549 QuestionId = GetFreeQuestionId ();\r
2550 } else {\r
2551 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2552 goto Err;\r
2553 }\r
2554 MarkQuestionIdUsed (QuestionId);\r
2555 }\r
2556\r
2557 pNode[0]->mQuestionId = QuestionId;\r
2558 pNode[1]->mQuestionId = QuestionId;\r
2559 pNode[2]->mQuestionId = QuestionId;\r
2560 pNode[0]->mQtype = QUESTION_DATE;\r
2561 pNode[1]->mQtype = QUESTION_DATE;\r
2562 pNode[2]->mQtype = QUESTION_DATE;\r
2563 pNode[0]->mNext = pNode[1];\r
2564 pNode[1]->mNext = pNode[2];\r
2565 pNode[2]->mNext = mQuestionList;\r
2566 mQuestionList = pNode[0];\r
2567\r
2568 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2569 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2570 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2571\r
2572 return;\r
2573\r
2574Err:\r
2575 for (Index = 0; Index < 3; Index++) {\r
2576 if (pNode[Index] != NULL) {\r
2577 delete pNode[Index];\r
2578 }\r
2579 }\r
2580 QuestionId = EFI_QUESTION_ID_INVALID;\r
2581}\r
2582\r
2583VOID\r
2584CVfrQuestionDB::RegisterNewDateQuestion (\r
2585 IN CHAR8 *Name,\r
2586 IN CHAR8 *BaseVarId,\r
2587 IN OUT EFI_QUESTION_ID &QuestionId\r
2588 )\r
2589{\r
2590 SVfrQuestionNode *pNode[3] = {NULL, };\r
2591 UINT32 Len;\r
2592 CHAR8 *VarIdStr[3] = {NULL, };\r
2593 CHAR8 Index;\r
2594\r
2595 if (BaseVarId == NULL) {\r
2596 return;\r
2597 }\r
2598\r
2599 Len = strlen (BaseVarId);\r
2600\r
2601 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2602 if (VarIdStr[0] != NULL) {\r
2603 strcpy (VarIdStr[0], BaseVarId);\r
2604 strcat (VarIdStr[0], ".Year");\r
2605 }\r
2606 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2607 if (VarIdStr[1] != NULL) {\r
2608 strcpy (VarIdStr[1], BaseVarId);\r
2609 strcat (VarIdStr[1], ".Month");\r
2610 }\r
2611 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2612 if (VarIdStr[2] != NULL) {\r
2613 strcpy (VarIdStr[2], BaseVarId);\r
2614 strcat (VarIdStr[2], ".Day");\r
2615 }\r
2616\r
2617 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
2618 goto Err;\r
2619 }\r
2620 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
2621 goto Err;\r
2622 }\r
2623 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
2624 goto Err;\r
2625 }\r
2626\r
2627 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2628 QuestionId = GetFreeQuestionId ();\r
2629 } else {\r
2630 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2631 goto Err;\r
2632 }\r
2633 MarkQuestionIdUsed (QuestionId);\r
2634 }\r
2635\r
2636 pNode[0]->mQuestionId = QuestionId;\r
2637 pNode[1]->mQuestionId = QuestionId;\r
2638 pNode[2]->mQuestionId = QuestionId;\r
2639 pNode[0]->mQtype = QUESTION_DATE;\r
2640 pNode[1]->mQtype = QUESTION_DATE;\r
2641 pNode[2]->mQtype = QUESTION_DATE;\r
2642 pNode[0]->mNext = pNode[1];\r
2643 pNode[1]->mNext = pNode[2];\r
2644 pNode[2]->mNext = mQuestionList;\r
2645 mQuestionList = pNode[0];\r
2646\r
2647 for (Index = 0; Index < 3; Index++) {\r
2648 if (VarIdStr[Index] != NULL) {\r
2649 delete VarIdStr[Index];\r
2650 }\r
2651 }\r
2652\r
2653 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2654 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2655 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2656\r
2657 return;\r
2658\r
2659Err:\r
2660 for (Index = 0; Index < 3; Index++) {\r
2661 if (pNode[Index] != NULL) {\r
2662 delete pNode[Index];\r
2663 }\r
2664\r
2665 if (VarIdStr[Index] != NULL) {\r
2666 delete VarIdStr[Index];\r
2667 }\r
2668 }\r
2669}\r
2670\r
2671VOID\r
2672CVfrQuestionDB::RegisterOldTimeQuestion (\r
2673 IN CHAR8 *HourVarId,\r
2674 IN CHAR8 *MinuteVarId,\r
2675 IN CHAR8 *SecondVarId,\r
2676 IN OUT EFI_QUESTION_ID &QuestionId\r
2677 )\r
2678{\r
2679 SVfrQuestionNode *pNode[3] = {NULL, };\r
2680 UINT32 Index;\r
2681\r
2682 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
2683 return;\r
2684 }\r
2685\r
2686 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
2687 goto Err;\r
2688 }\r
2689 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
2690 goto Err;\r
2691 }\r
2692 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
2693 goto Err;\r
2694 }\r
2695\r
2696 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2697 QuestionId = GetFreeQuestionId ();\r
2698 } else {\r
2699 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2700 goto Err;\r
2701 }\r
2702 MarkQuestionIdUsed (QuestionId);\r
2703 }\r
2704\r
2705 pNode[0]->mQuestionId = QuestionId;\r
2706 pNode[1]->mQuestionId = QuestionId;\r
2707 pNode[2]->mQuestionId = QuestionId;\r
2708 pNode[0]->mQtype = QUESTION_TIME;\r
2709 pNode[1]->mQtype = QUESTION_TIME;\r
2710 pNode[2]->mQtype = QUESTION_TIME;\r
2711 pNode[0]->mNext = pNode[1];\r
2712 pNode[1]->mNext = pNode[2];\r
2713 pNode[2]->mNext = mQuestionList;\r
2714 mQuestionList = pNode[0];\r
2715\r
2716 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2717 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2718 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2719\r
2720 return;\r
2721\r
2722Err:\r
2723 for (Index = 0; Index < 3; Index++) {\r
2724 if (pNode[Index] != NULL) {\r
2725 delete pNode[Index];\r
2726 }\r
2727 }\r
2728 QuestionId = EFI_QUESTION_ID_INVALID;\r
2729}\r
2730\r
2731VOID\r
2732CVfrQuestionDB::RegisterNewTimeQuestion (\r
2733 IN CHAR8 *Name,\r
2734 IN CHAR8 *BaseVarId,\r
2735 IN OUT EFI_QUESTION_ID &QuestionId\r
2736 )\r
2737{\r
2738 SVfrQuestionNode *pNode[3] = {NULL, };\r
2739 UINT32 Len;\r
2740 CHAR8 *VarIdStr[3] = {NULL, };\r
2741 CHAR8 Index;\r
2742\r
2743 if (BaseVarId == NULL) {\r
2744 return;\r
2745 }\r
2746\r
2747 Len = strlen (BaseVarId);\r
2748\r
2749 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2750 if (VarIdStr[0] != NULL) {\r
2751 strcpy (VarIdStr[0], BaseVarId);\r
2752 strcat (VarIdStr[0], ".Hour");\r
2753 }\r
2754 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2755 if (VarIdStr[1] != NULL) {\r
2756 strcpy (VarIdStr[1], BaseVarId);\r
2757 strcat (VarIdStr[1], ".Minute");\r
2758 }\r
2759 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2760 if (VarIdStr[2] != NULL) {\r
2761 strcpy (VarIdStr[2], BaseVarId);\r
2762 strcat (VarIdStr[2], ".Second");\r
2763 }\r
2764\r
2765 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
2766 goto Err;\r
2767 }\r
2768 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
2769 goto Err;\r
2770 }\r
2771 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
2772 goto Err;\r
2773 }\r
2774\r
2775 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2776 QuestionId = GetFreeQuestionId ();\r
2777 } else {\r
2778 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2779 goto Err;\r
2780 }\r
2781 MarkQuestionIdUsed (QuestionId);\r
2782 }\r
2783\r
2784 pNode[0]->mQuestionId = QuestionId;\r
2785 pNode[1]->mQuestionId = QuestionId;\r
2786 pNode[2]->mQuestionId = QuestionId;\r
2787 pNode[0]->mQtype = QUESTION_TIME;\r
2788 pNode[1]->mQtype = QUESTION_TIME;\r
2789 pNode[2]->mQtype = QUESTION_TIME;\r
2790 pNode[0]->mNext = pNode[1];\r
2791 pNode[1]->mNext = pNode[2];\r
2792 pNode[2]->mNext = mQuestionList;\r
2793 mQuestionList = pNode[0];\r
2794\r
2795 for (Index = 0; Index < 3; Index++) {\r
2796 if (VarIdStr[Index] != NULL) {\r
2797 delete VarIdStr[Index];\r
2798 }\r
2799 }\r
2800\r
2801 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2802 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2803 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2804\r
2805 return;\r
2806\r
2807Err:\r
2808 for (Index = 0; Index < 3; Index++) {\r
2809 if (pNode[Index] != NULL) {\r
2810 delete pNode[Index];\r
2811 }\r
2812\r
2813 if (VarIdStr[Index] != NULL) {\r
2814 delete VarIdStr[Index];\r
2815 }\r
2816 }\r
2817}\r
2818\r
2819VOID \r
2820CVfrQuestionDB::RegisterRefQuestion (\r
2821 IN CHAR8 *Name,\r
2822 IN CHAR8 *BaseVarId,\r
2823 IN OUT EFI_QUESTION_ID &QuestionId\r
2824 )\r
2825{\r
2826 SVfrQuestionNode *pNode[4] = {NULL, };\r
2827 UINT32 Len;\r
2828 CHAR8 *VarIdStr[4] = {NULL, };\r
2829 CHAR8 Index;\r
2830\r
2831 if (BaseVarId == NULL) {\r
2832 return;\r
2833 }\r
2834\r
2835 Len = strlen (BaseVarId);\r
2836\r
2837 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
2838 if (VarIdStr[0] != NULL) {\r
2839 strcpy (VarIdStr[0], BaseVarId);\r
2840 strcat (VarIdStr[0], ".QuestionId");\r
2841 }\r
2842 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
2843 if (VarIdStr[1] != NULL) {\r
2844 strcpy (VarIdStr[1], BaseVarId);\r
2845 strcat (VarIdStr[1], ".FormId");\r
2846 }\r
2847 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
2848 if (VarIdStr[2] != NULL) {\r
2849 strcpy (VarIdStr[2], BaseVarId);\r
2850 strcat (VarIdStr[2], ".FormSetGuid");\r
2851 }\r
2852 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
2853 if (VarIdStr[3] != NULL) {\r
2854 strcpy (VarIdStr[3], BaseVarId);\r
2855 strcat (VarIdStr[3], ".DevicePath");\r
2856 }\r
2857\r
2858 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {\r
2859 goto Err;\r
2860 }\r
2861 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {\r
2862 goto Err;\r
2863 }\r
2864 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {\r
2865 goto Err;\r
2866 }\r
2867 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {\r
2868 goto Err;\r
2869 }\r
2870\r
2871 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2872 QuestionId = GetFreeQuestionId ();\r
2873 } else {\r
2874 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2875 goto Err;\r
2876 }\r
2877 MarkQuestionIdUsed (QuestionId);\r
2878 }\r
2879\r
2880 pNode[0]->mQuestionId = QuestionId;\r
2881 pNode[1]->mQuestionId = QuestionId;\r
2882 pNode[2]->mQuestionId = QuestionId;\r
2883 pNode[3]->mQuestionId = QuestionId; \r
2884 pNode[0]->mQtype = QUESTION_REF;\r
2885 pNode[1]->mQtype = QUESTION_REF;\r
2886 pNode[2]->mQtype = QUESTION_REF;\r
2887 pNode[3]->mQtype = QUESTION_REF; \r
2888 pNode[0]->mNext = pNode[1];\r
2889 pNode[1]->mNext = pNode[2];\r
2890 pNode[2]->mNext = pNode[3];\r
2891 pNode[3]->mNext = mQuestionList; \r
2892 mQuestionList = pNode[0];\r
2893\r
2894 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2895 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2896 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2897 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2898\r
2899 return;\r
2900\r
2901 Err:\r
2902 for (Index = 0; Index < 4; Index++) {\r
2903 if (pNode[Index] != NULL) {\r
2904 delete pNode[Index];\r
2905 }\r
2906\r
2907 if (VarIdStr[Index] != NULL) {\r
2908 delete VarIdStr[Index];\r
2909 }\r
2910 }\r
2911}\r
2912\r
2913EFI_VFR_RETURN_CODE\r
2914CVfrQuestionDB::UpdateQuestionId (\r
2915 IN EFI_QUESTION_ID QId,\r
2916 IN EFI_QUESTION_ID NewQId\r
2917 )\r
2918{\r
2919 SVfrQuestionNode *pNode = NULL;\r
2920 \r
2921 if (QId == NewQId) {\r
2922 // don't update\r
2923 return VFR_RETURN_SUCCESS;\r
2924 }\r
2925 \r
2926 //\r
2927 // For Framework Vfr, don't check question ID conflict.\r
2928 // \r
2929 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
2930 return VFR_RETURN_REDEFINED;\r
2931 }\r
2932\r
2933 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2934 if (pNode->mQuestionId == QId) {\r
2935 break;\r
2936 }\r
2937 }\r
2938\r
2939 if (pNode == NULL) {\r
2940 return VFR_RETURN_UNDEFINED;\r
2941 }\r
2942\r
2943 MarkQuestionIdUnused (QId);\r
2944 pNode->mQuestionId = NewQId;\r
2945 MarkQuestionIdUsed (NewQId);\r
2946\r
2947 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
2948\r
2949 return VFR_RETURN_SUCCESS;\r
2950}\r
2951\r
2952VOID\r
2953CVfrQuestionDB::GetQuestionId (\r
2954 IN CHAR8 *Name,\r
2955 IN CHAR8 *VarIdStr,\r
2956 OUT EFI_QUESTION_ID &QuestionId,\r
2957 OUT UINT32 &BitMask,\r
2958 OUT EFI_QUESION_TYPE *QType\r
2959 )\r
2960{\r
2961 SVfrQuestionNode *pNode;\r
2962\r
2963 QuestionId = EFI_QUESTION_ID_INVALID;\r
2964 BitMask = 0x00000000;\r
2965 if (QType != NULL) {\r
2966 *QType = QUESTION_NORMAL;\r
2967 }\r
2968\r
2969 if ((Name == NULL) && (VarIdStr == NULL)) {\r
2970 return ;\r
2971 }\r
2972\r
2973 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2974 if (Name != NULL) {\r
2975 if (strcmp (pNode->mName, Name) != 0) {\r
2976 continue;\r
2977 }\r
2978 }\r
2979\r
2980 if (VarIdStr != NULL) {\r
2981 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
2982 continue;\r
2983 }\r
2984 }\r
2985\r
2986 QuestionId = pNode->mQuestionId;\r
2987 BitMask = pNode->mBitMask;\r
2988 if (QType != NULL) {\r
2989 *QType = pNode->mQtype;\r
2990 }\r
2991 break;\r
2992 }\r
2993\r
2994 return ;\r
2995}\r
2996\r
2997EFI_VFR_RETURN_CODE\r
2998CVfrQuestionDB::FindQuestion (\r
2999 IN EFI_QUESTION_ID QuestionId\r
3000 )\r
3001{\r
3002 SVfrQuestionNode *pNode;\r
3003\r
3004 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3005 return VFR_RETURN_INVALID_PARAMETER;\r
3006 }\r
3007\r
3008 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3009 if (pNode->mQuestionId == QuestionId) {\r
3010 return VFR_RETURN_SUCCESS;\r
3011 }\r
3012 }\r
3013\r
3014 return VFR_RETURN_UNDEFINED;\r
3015}\r
3016\r
3017EFI_VFR_RETURN_CODE\r
3018CVfrQuestionDB::FindQuestion (\r
3019 IN CHAR8 *Name\r
3020 )\r
3021{\r
3022 SVfrQuestionNode *pNode;\r
3023\r
3024 if (Name == NULL) {\r
3025 return VFR_RETURN_FATAL_ERROR;\r
3026 }\r
3027\r
3028 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3029 if (strcmp (pNode->mName, Name) == 0) {\r
3030 return VFR_RETURN_SUCCESS;\r
3031 }\r
3032 }\r
3033\r
3034 return VFR_RETURN_UNDEFINED;\r
3035}\r
3036\r
3037CVfrStringDB::CVfrStringDB ()\r
3038{\r
3039 mStringFileName = NULL;\r
3040}\r
3041\r
3042CVfrStringDB::~CVfrStringDB ()\r
3043{\r
3044 if (mStringFileName != NULL) {\r
3045 delete mStringFileName;\r
3046 }\r
3047 mStringFileName = NULL;\r
3048}\r
3049\r
3050\r
3051VOID \r
3052CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
3053{\r
3054 UINT32 FileLen = 0;\r
3055\r
3056 if (StringFileName == NULL) {\r
3057 return;\r
3058 }\r
3059\r
3060 FileLen = strlen (StringFileName) + 1;\r
3061 mStringFileName = new CHAR8[FileLen];\r
3062 if (mStringFileName == NULL) {\r
3063 return;\r
3064 }\r
3065\r
3066 strcpy (mStringFileName, StringFileName);\r
3067 mStringFileName[FileLen - 1] = '\0';\r
3068}\r
3069\r
3070CHAR8 *\r
3071CVfrStringDB::GetVarStoreNameFormStringId (\r
3072 IN EFI_STRING_ID StringId\r
3073 )\r
3074{\r
3075 FILE *pInFile = NULL;\r
3076 UINT32 NameOffset;\r
3077 UINT32 Length;\r
3078 UINT8 *StringPtr;\r
3079 CHAR8 *StringName;\r
3080 CHAR16 *UnicodeString;\r
3081 CHAR8 *VarStoreName = NULL;\r
3082 CHAR8 *DestTmp;\r
3083 UINT8 *Current;\r
3084 EFI_STATUS Status;\r
3085 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];\r
3086 UINT8 BlockType;\r
3087 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
3088 \r
3089 if (mStringFileName == '\0' ) {\r
3090 return NULL;\r
3091 }\r
3092\r
3093 if ((pInFile = fopen (mStringFileName, "rb")) == NULL) {\r
3094 return NULL;\r
3095 }\r
3096\r
3097 //\r
3098 // Get file length.\r
3099 //\r
3100 fseek (pInFile, 0, SEEK_END);\r
3101 Length = ftell (pInFile);\r
3102 fseek (pInFile, 0, SEEK_SET);\r
3103\r
3104 //\r
3105 // Get file data.\r
3106 //\r
3107 StringPtr = new UINT8[Length];\r
3108 if (StringPtr == NULL) {\r
3109 fclose (pInFile);\r
3110 return NULL;\r
3111 }\r
3112 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
3113 fclose (pInFile);\r
3114\r
3115 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
3116 //\r
3117 // Check the String package.\r
3118 //\r
3119 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
3120 delete StringPtr;\r
3121 return NULL;\r
3122 }\r
3123\r
3124 //\r
3125 // Search the language, only search the "en-US".\r
3126 //\r
3127 Current = StringPtr;\r
3128 while (strcmp (PkgHeader->Language, "en-US") != 0) {\r
3129 Current += PkgHeader->Header.Length;\r
3130 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
3131 //\r
3132 // If can't find "en-US" string package, just return the first string package.\r
3133 //\r
3134 if (Current - StringPtr >= Length) {\r
3135 Current = StringPtr;\r
3136 break;\r
3137 }\r
3138 }\r
3139\r
3140 Current += PkgHeader->HdrSize;\r
3141 //\r
3142 // Find the string block according the stringId.\r
3143 //\r
3144 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
3145 if (Status != EFI_SUCCESS) {\r
3146 delete StringPtr;\r
3147 return NULL;\r
3148 }\r
3149\r
3150 //\r
3151 // Get varstore name according the string type.\r
3152 //\r
3153 switch (BlockType) {\r
3154 case EFI_HII_SIBT_STRING_SCSU:\r
3155 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3156 case EFI_HII_SIBT_STRINGS_SCSU:\r
3157 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3158 StringName = (CHAR8*)(Current + NameOffset);\r
3159 VarStoreName = new CHAR8[strlen(StringName) + 1];\r
3160 strcpy (VarStoreName, StringName);\r
3161 break;\r
3162 case EFI_HII_SIBT_STRING_UCS2:\r
3163 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3164 case EFI_HII_SIBT_STRINGS_UCS2:\r
3165 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3166 UnicodeString = (CHAR16*)(Current + NameOffset);\r
3167 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
3168 DestTmp = new CHAR8[Length / 2 + 1];\r
3169 VarStoreName = DestTmp;\r
3170 while (*UnicodeString != '\0') {\r
3171 *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
3172 }\r
3173 *DestTmp = '\0';\r
3174 break;\r
3175 default:\r
3176 break;\r
3177 }\r
3178\r
3179 delete StringPtr;\r
3180\r
3181 return VarStoreName;\r
3182}\r
3183\r
3184EFI_STATUS\r
3185CVfrStringDB::FindStringBlock (\r
3186 IN UINT8 *StringData,\r
3187 IN EFI_STRING_ID StringId,\r
3188 OUT UINT32 *StringTextOffset,\r
3189 OUT UINT8 *BlockType\r
3190 )\r
3191{\r
3192 UINT8 *BlockHdr;\r
3193 EFI_STRING_ID CurrentStringId;\r
3194 UINT32 BlockSize;\r
3195 UINT32 Index;\r
3196 UINT8 *StringTextPtr;\r
3197 UINT32 Offset;\r
3198 UINT16 StringCount;\r
3199 UINT16 SkipCount;\r
3200 UINT8 Length8;\r
3201 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
3202 UINT32 Length32;\r
3203 UINT32 StringSize;\r
3204\r
3205 CurrentStringId = 1;\r
3206\r
3207 //\r
3208 // Parse the string blocks to get the string text and font.\r
3209 //\r
3210 BlockHdr = StringData;\r
3211 BlockSize = 0;\r
3212 Offset = 0;\r
3213 while (*BlockHdr != EFI_HII_SIBT_END) {\r
3214 switch (*BlockHdr) {\r
3215 case EFI_HII_SIBT_STRING_SCSU:\r
3216 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3217 StringTextPtr = BlockHdr + Offset;\r
3218 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3219 CurrentStringId++;\r
3220 break;\r
3221\r
3222 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3223 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3224 StringTextPtr = BlockHdr + Offset;\r
3225 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3226 CurrentStringId++;\r
3227 break;\r
3228\r
3229 case EFI_HII_SIBT_STRINGS_SCSU:\r
3230 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3231 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
3232 BlockSize += StringTextPtr - BlockHdr;\r
3233\r
3234 for (Index = 0; Index < StringCount; Index++) {\r
3235 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3236 if (CurrentStringId == StringId) {\r
3237 *BlockType = *BlockHdr;\r
3238 *StringTextOffset = StringTextPtr - StringData;\r
3239 return EFI_SUCCESS;\r
3240 }\r
3241 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3242 CurrentStringId++;\r
3243 }\r
3244 break;\r
3245\r
3246 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3247 memcpy (\r
3248 &StringCount,\r
3249 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3250 sizeof (UINT16)\r
3251 );\r
3252 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3253 BlockSize += StringTextPtr - BlockHdr;\r
3254\r
3255 for (Index = 0; Index < StringCount; Index++) {\r
3256 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3257 if (CurrentStringId == StringId) {\r
3258 *BlockType = *BlockHdr;\r
3259 *StringTextOffset = StringTextPtr - StringData;\r
3260 return EFI_SUCCESS;\r
3261 }\r
3262 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3263 CurrentStringId++;\r
3264 }\r
3265 break;\r
3266\r
3267 case EFI_HII_SIBT_STRING_UCS2:\r
3268 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3269 StringTextPtr = BlockHdr + Offset;\r
3270 //\r
3271 // Use StringSize to store the size of the specified string, including the NULL\r
3272 // terminator.\r
3273 //\r
3274 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3275 BlockSize += Offset + StringSize;\r
3276 CurrentStringId++;\r
3277 break;\r
3278\r
3279 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3280 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3281 StringTextPtr = BlockHdr + Offset;\r
3282 //\r
3283 // Use StrSize to store the size of the specified string, including the NULL\r
3284 // terminator.\r
3285 //\r
3286 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3287 BlockSize += Offset + StringSize;\r
3288 CurrentStringId++;\r
3289 break;\r
3290\r
3291 case EFI_HII_SIBT_STRINGS_UCS2:\r
3292 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
3293 StringTextPtr = BlockHdr + Offset;\r
3294 BlockSize += Offset;\r
3295 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3296 for (Index = 0; Index < StringCount; Index++) {\r
3297 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3298 BlockSize += StringSize;\r
3299 if (CurrentStringId == StringId) {\r
3300 *BlockType = *BlockHdr;\r
3301 *StringTextOffset = StringTextPtr - StringData;\r
3302 return EFI_SUCCESS;\r
3303 }\r
3304 StringTextPtr = StringTextPtr + StringSize;\r
3305 CurrentStringId++;\r
3306 }\r
3307 break;\r
3308\r
3309 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3310 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3311 StringTextPtr = BlockHdr + Offset;\r
3312 BlockSize += Offset;\r
3313 memcpy (\r
3314 &StringCount,\r
3315 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3316 sizeof (UINT16)\r
3317 );\r
3318 for (Index = 0; Index < StringCount; Index++) {\r
3319 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3320 BlockSize += StringSize;\r
3321 if (CurrentStringId == StringId) {\r
3322 *BlockType = *BlockHdr;\r
3323 *StringTextOffset = StringTextPtr - StringData;\r
3324 return EFI_SUCCESS;\r
3325 }\r
3326 StringTextPtr = StringTextPtr + StringSize;\r
3327 CurrentStringId++;\r
3328 }\r
3329 break;\r
3330\r
3331 case EFI_HII_SIBT_DUPLICATE:\r
3332 if (CurrentStringId == StringId) {\r
3333 //\r
3334 // Incoming StringId is an id of a duplicate string block.\r
3335 // Update the StringId to be the previous string block.\r
3336 // Go back to the header of string block to search.\r
3337 //\r
3338 memcpy (\r
3339 &StringId,\r
3340 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
3341 sizeof (EFI_STRING_ID)\r
3342 );\r
3343 CurrentStringId = 1;\r
3344 BlockSize = 0;\r
3345 } else {\r
3346 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
3347 CurrentStringId++;\r
3348 }\r
3349 break;\r
3350\r
3351 case EFI_HII_SIBT_SKIP1:\r
3352 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
3353 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3354 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
3355 break;\r
3356\r
3357 case EFI_HII_SIBT_SKIP2:\r
3358 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3359 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3360 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
3361 break;\r
3362\r
3363 case EFI_HII_SIBT_EXT1:\r
3364 memcpy (\r
3365 &Length8,\r
3366 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3367 sizeof (UINT8)\r
3368 );\r
3369 BlockSize += Length8;\r
3370 break;\r
3371\r
3372 case EFI_HII_SIBT_EXT2:\r
3373 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
3374 BlockSize += Ext2.Length;\r
3375 break;\r
3376\r
3377 case EFI_HII_SIBT_EXT4:\r
3378 memcpy (\r
3379 &Length32,\r
3380 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3381 sizeof (UINT32)\r
3382 );\r
3383\r
3384 BlockSize += Length32;\r
3385 break;\r
3386\r
3387 default:\r
3388 break;\r
3389 }\r
3390\r
3391 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
3392 *StringTextOffset = BlockHdr - StringData + Offset;\r
3393 *BlockType = *BlockHdr;\r
3394\r
3395 if (StringId == CurrentStringId - 1) {\r
3396 //\r
3397 // if only one skip item, return EFI_NOT_FOUND.\r
3398 //\r
3399 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
3400 return EFI_NOT_FOUND;\r
3401 } else {\r
3402 return EFI_SUCCESS;\r
3403 }\r
3404 }\r
3405\r
3406 if (StringId < CurrentStringId - 1) {\r
3407 return EFI_NOT_FOUND;\r
3408 }\r
3409 }\r
3410 BlockHdr = StringData + BlockSize;\r
3411 }\r
3412\r
3413 return EFI_NOT_FOUND;\r
3414}\r
3415\r
3416UINT32\r
3417CVfrStringDB::GetUnicodeStringTextSize (\r
3418 IN UINT8 *StringSrc\r
3419 )\r
3420{\r
3421 UINT32 StringSize;\r
3422 CHAR16 *StringPtr;\r
3423\r
3424 StringSize = sizeof (CHAR16);\r
3425 StringPtr = (UINT16*)StringSrc;\r
3426 while (*StringPtr++ != L'\0') {\r
3427 StringSize += sizeof (CHAR16);\r
3428 }\r
3429\r
3430 return StringSize;\r
3431}\r
3432\r
3433BOOLEAN VfrCompatibleMode = FALSE;\r
3434\r
3435CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
3436\r
3437\r