]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
Fix a bug in secure boot configuration driver: Enroll DB/KEK will disable Attempt...
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 Vfr common library functions.\r
4\r
64b2609f 5Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "stdlib.h"\r
18#include "VfrUtilityLib.h"\r
19#include "VfrFormPkg.h"\r
20\r
21VOID\r
22CVfrBinaryOutput::WriteLine (\r
52302d4d
LG
23 IN FILE *pFile,\r
24 IN UINT32 LineBytes,\r
25 IN CONST CHAR8 *LineHeader,\r
26 IN CHAR8 *BlkBuf,\r
27 IN UINT32 BlkSize\r
30fdf114
LG
28 )\r
29{\r
30 UINT32 Index;\r
31\r
32 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
33 return;\r
34 }\r
35\r
36 for (Index = 0; Index < BlkSize; Index++) {\r
37 if ((Index % LineBytes) == 0) {\r
38 fprintf (pFile, "\n%s", LineHeader);\r
39 }\r
40 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
41 }\r
42}\r
43\r
44VOID\r
45CVfrBinaryOutput::WriteEnd (\r
52302d4d
LG
46 IN FILE *pFile,\r
47 IN UINT32 LineBytes,\r
48 IN CONST CHAR8 *LineHeader,\r
49 IN CHAR8 *BlkBuf,\r
50 IN UINT32 BlkSize\r
30fdf114
LG
51 )\r
52{\r
53 UINT32 Index;\r
54\r
55 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
56 return;\r
57 }\r
58\r
59 for (Index = 0; Index < BlkSize - 1; Index++) {\r
60 if ((Index % LineBytes) == 0) {\r
61 fprintf (pFile, "\n%s", LineHeader);\r
62 }\r
63 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
64 }\r
65\r
66 if ((Index % LineBytes) == 0) {\r
67 fprintf (pFile, "\n%s", LineHeader);\r
68 }\r
69 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
70}\r
71\r
72SConfigInfo::SConfigInfo (\r
73 IN UINT8 Type, \r
74 IN UINT16 Offset, \r
75 IN UINT32 Width, \r
76 IN EFI_IFR_TYPE_VALUE Value\r
77 )\r
78{\r
79 mNext = NULL;\r
80 mOffset = Offset;\r
81 mWidth = (UINT16)Width;\r
82 mValue = new UINT8[mWidth];\r
83 if (mValue == NULL) {\r
84 return;\r
85 }\r
86\r
87 switch (Type) {\r
88 case EFI_IFR_TYPE_NUM_SIZE_8 :\r
89 memcpy (mValue, &Value.u8, mWidth);\r
90 break;\r
91 case EFI_IFR_TYPE_NUM_SIZE_16 :\r
92 memcpy (mValue, &Value.u16, mWidth);\r
93 break;\r
94 case EFI_IFR_TYPE_NUM_SIZE_32 :\r
95 memcpy (mValue, &Value.u32, mWidth);\r
96 break;\r
97 case EFI_IFR_TYPE_NUM_SIZE_64 :\r
98 memcpy (mValue, &Value.u64, mWidth);\r
99 break;\r
100 case EFI_IFR_TYPE_BOOLEAN :\r
101 memcpy (mValue, &Value.b, mWidth);\r
102 break;\r
103 case EFI_IFR_TYPE_TIME :\r
104 memcpy (mValue, &Value.time, mWidth);\r
105 break;\r
106 case EFI_IFR_TYPE_DATE :\r
107 memcpy (mValue, &Value.date, mWidth);\r
108 break;\r
109 case EFI_IFR_TYPE_STRING :\r
110 memcpy (mValue, &Value.string, mWidth);\r
111 break;\r
112 case EFI_IFR_TYPE_OTHER :\r
113 return;\r
114 }\r
115}\r
116\r
117SConfigInfo::~SConfigInfo (\r
118 VOID\r
119 )\r
120{\r
121 BUFFER_SAFE_FREE (mValue);\r
122}\r
123\r
124SConfigItem::SConfigItem (\r
125 IN CHAR8 *Name,\r
126 IN CHAR8 *Id\r
127 )\r
128{\r
129 mName = NULL;\r
130 mId = 0;\r
131 mInfoStrList = NULL;\r
132 mNext = NULL;\r
133\r
134 if (Name != NULL) {\r
135 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {\r
136 strcpy (mName, Name);\r
137 }\r
138 }\r
139\r
140 if (Id != NULL) {\r
141 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
142 strcpy (mId, Id);\r
143 }\r
144 }\r
145}\r
146\r
147SConfigItem::SConfigItem (\r
148 IN CHAR8 *Name,\r
149 IN CHAR8 *Id,\r
150 IN UINT8 Type,\r
151 IN UINT16 Offset,\r
152 IN UINT16 Width,\r
153 IN EFI_IFR_TYPE_VALUE Value\r
154 )\r
155{\r
156 mName = NULL;\r
157 mId = NULL;\r
158 mInfoStrList = NULL;\r
159 mNext = NULL;\r
160\r
161 if (Name != NULL) {\r
162 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {\r
163 strcpy (mName, Name);\r
164 }\r
165 }\r
166\r
167 if (Id != NULL) {\r
168 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
169 strcpy (mId, Id);\r
170 }\r
171 }\r
172\r
173 mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);\r
174}\r
175\r
176SConfigItem::~SConfigItem (\r
177 VOID\r
178 )\r
179{\r
180 SConfigInfo *Info;\r
181\r
182 BUFFER_SAFE_FREE (mName);\r
183 BUFFER_SAFE_FREE (mId);\r
184 while (mInfoStrList != NULL) {\r
185 Info = mInfoStrList;\r
186 mInfoStrList = mInfoStrList->mNext;\r
187\r
188 BUFFER_SAFE_FREE (Info);\r
189 }\r
190}\r
191\r
192UINT8\r
193CVfrBufferConfig::Register (\r
194 IN CHAR8 *Name,\r
195 IN CHAR8 *Id\r
196 )\r
197{\r
198 SConfigItem *pNew;\r
199\r
200 if (Select (Name) == 0) {\r
201 return 1;\r
202 }\r
203\r
204 if ((pNew = new SConfigItem (Name, Id)) == NULL) {\r
205 return 2;\r
206 }\r
207 if (mItemListHead == NULL) {\r
208 mItemListHead = pNew;\r
209 mItemListTail = pNew;\r
210 } else {\r
211 mItemListTail->mNext = pNew;\r
212 mItemListTail = pNew;\r
213 }\r
214 mItemListPos = pNew;\r
215\r
216 return 0;\r
217}\r
218\r
219VOID\r
220CVfrBufferConfig::Open (\r
221 VOID\r
222 )\r
223{\r
224 mItemListPos = mItemListHead;\r
225}\r
226\r
227BOOLEAN\r
228CVfrBufferConfig::Eof(\r
229 VOID\r
230 )\r
231{\r
232 return (mItemListPos == NULL) ? TRUE : FALSE;\r
233}\r
234\r
235UINT8\r
236CVfrBufferConfig::Select (\r
237 IN CHAR8 *Name,\r
238 IN CHAR8 *Id\r
239 )\r
240{\r
241 SConfigItem *p;\r
242\r
243 if (Name == NULL) {\r
244 mItemListPos = mItemListHead;\r
245 return 0;\r
246 } else {\r
247 for (p = mItemListHead; p != NULL; p = p->mNext) {\r
248 if (strcmp (p->mName, Name) != 0) {\r
249 continue;\r
250 }\r
251\r
252 if (Id != NULL) {\r
253 if (p->mId == NULL || strcmp (p->mId, Id) != 0) {\r
254 continue;\r
255 }\r
256 } else if (p->mId != NULL) {\r
257 continue;\r
258 }\r
259\r
260 mItemListPos = p;\r
261 return 0;\r
262 }\r
263 }\r
264\r
265 return 1;\r
266}\r
267\r
268UINT8\r
269CVfrBufferConfig::Write (\r
270 IN CONST CHAR8 Mode,\r
271 IN CHAR8 *Name,\r
272 IN CHAR8 *Id,\r
273 IN UINT8 Type,\r
274 IN UINT16 Offset,\r
275 IN UINT32 Width,\r
276 IN EFI_IFR_TYPE_VALUE Value\r
277 )\r
278{\r
279 UINT8 Ret;\r
280 SConfigItem *pItem;\r
281 SConfigInfo *pInfo;\r
282\r
283 if ((Ret = Select (Name)) != 0) {\r
284 return Ret;\r
285 }\r
286\r
287 switch (Mode) {\r
288 case 'a' : // add\r
289 if (Select (Name, Id) != 0) {\r
52302d4d 290 if ((pItem = new SConfigItem (Name, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {\r
30fdf114
LG
291 return 2;\r
292 }\r
293 if (mItemListHead == NULL) {\r
294 mItemListHead = pItem;\r
295 mItemListTail = pItem;\r
296 } else {\r
297 mItemListTail->mNext = pItem;\r
298 mItemListTail = pItem;\r
299 }\r
300 mItemListPos = pItem;\r
301 } else {\r
302 // tranverse the list to find out if there's already the value for the same offset\r
303 for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {\r
304 if (pInfo->mOffset == Offset) {\r
305 // check if the value and width are the same; return error if not\r
306 if ((Id != NULL) && (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0)) {\r
307 return VFR_RETURN_DEFAULT_VALUE_REDEFINED;\r
308 }\r
309 return 0;\r
310 }\r
311 }\r
312 if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {\r
313 return 2;\r
314 }\r
315 pInfo->mNext = mItemListPos->mInfoStrList;\r
316 mItemListPos->mInfoStrList = pInfo;\r
317 }\r
318 break;\r
319\r
320 case 'd' : // delete\r
321 if (mItemListHead == mItemListPos) {\r
322 mItemListHead = mItemListPos->mNext;\r
323 delete mItemListPos;\r
324 break;\r
325 }\r
326\r
327 for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)\r
328 ;\r
329\r
330 pItem->mNext = mItemListPos->mNext;\r
331 if (mItemListTail == mItemListPos) {\r
332 mItemListTail = pItem;\r
333 }\r
334 delete mItemListPos;\r
335 mItemListPos = pItem->mNext;\r
336 break;\r
337\r
338 case 'i' : // set info\r
339 if (mItemListPos->mId != NULL) {\r
340 delete mItemListPos->mId;\r
341 }\r
342 mItemListPos->mId = NULL;\r
343 if (Id != NULL) {\r
344 if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {\r
345 return 2;\r
346 }\r
347 strcpy (mItemListPos->mId, Id);\r
348 }\r
349 break;\r
350\r
351 default :\r
352 return 1;\r
353 }\r
354\r
355 return 0;\r
356}\r
357\r
358\r
359VOID\r
360CVfrBufferConfig::Close (\r
361 VOID\r
362 )\r
363{\r
364 mItemListPos = NULL;\r
365}\r
366\r
367#define BYTES_PRE_LINE 0x10\r
368\r
369VOID\r
370CVfrBufferConfig::OutputCFile (\r
371 IN FILE *pFile,\r
372 IN CHAR8 *BaseName\r
373 )\r
374{\r
375 CVfrBinaryOutput Output;\r
376 SConfigItem *Item;\r
377 SConfigInfo *Info;\r
378 UINT32 TotalLen;\r
379\r
380 if (pFile == NULL) {\r
381 return;\r
382 }\r
383\r
384 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {\r
385 if (Item->mId != NULL || Item->mInfoStrList == NULL) {\r
386 continue;\r
387 }\r
388 fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);\r
389\r
390 TotalLen = sizeof (UINT32);\r
391 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
392 TotalLen += sizeof (UINT16) * 2;\r
393 }\r
394 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));\r
395\r
396 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
397 fprintf (pFile, "\n");\r
398 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));\r
399 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));\r
400 }\r
401 fprintf (pFile, "\n};\n");\r
402 }\r
403\r
404 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {\r
405 if (Item->mId != NULL && Item->mInfoStrList != NULL) {\r
406 fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);\r
407\r
408 TotalLen = sizeof (UINT32);\r
409 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
410 TotalLen += Info->mWidth + sizeof (UINT16) * 2;\r
411 }\r
412 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));\r
413\r
414 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
415 fprintf (pFile, "\n");\r
416 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));\r
417 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));\r
418 if (Info->mNext == NULL) {\r
419 Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);\r
420 } else {\r
421 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);\r
422 }\r
423 }\r
424 fprintf (pFile, "\n};\n");\r
425 }\r
426 }\r
427}\r
428\r
429CVfrBufferConfig::CVfrBufferConfig (\r
430 VOID\r
431 )\r
432{\r
433 mItemListHead = NULL;\r
434 mItemListTail = NULL;\r
435 mItemListPos = NULL;\r
436}\r
437\r
438CVfrBufferConfig::~CVfrBufferConfig (\r
439 VOID\r
440 )\r
441{\r
442 SConfigItem *p;\r
443\r
444 while (mItemListHead != NULL) {\r
445 p = mItemListHead;\r
446 mItemListHead = mItemListHead->mNext;\r
447 delete p;\r
448 }\r
449\r
450 mItemListHead = NULL;\r
451 mItemListTail = NULL;\r
452 mItemListPos = NULL;\r
453}\r
454\r
455CVfrBufferConfig gCVfrBufferConfig;\r
456\r
457static struct {\r
52302d4d 458 CONST CHAR8 *mTypeName;\r
30fdf114
LG
459 UINT8 mType;\r
460 UINT32 mSize;\r
461 UINT32 mAlign;\r
462} gInternalTypesTable [] = {\r
463 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},\r
464 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},\r
465 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},\r
466 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},\r
467 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},\r
468 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},\r
469 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},\r
470 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},\r
4234283c 471 {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},\r
30fdf114
LG
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
da92f276
LG
626 if (*VarStr == '.') {\r
627 VarStr++;\r
628 }\r
30fdf114
LG
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
4234283c 639 IN CONST CHAR8 *FName,\r
30fdf114
LG
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
4234283c
LG
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
30fdf114
LG
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
52302d4d 765 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);\r
30fdf114
LG
766 pYearField->mOffset = 0;\r
767 pYearField->mNext = pMonthField;\r
768 pYearField->mArrayNum = 0;\r
769\r
770 strcpy (pMonthField->mFieldName, "Month");\r
52302d4d
LG
771 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);\r
772 pMonthField->mOffset = 2;\r
30fdf114
LG
773 pMonthField->mNext = pDayField;\r
774 pMonthField->mArrayNum = 0;\r
775\r
776 strcpy (pDayField->mFieldName, "Day");\r
52302d4d
LG
777 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);\r
778 pDayField->mOffset = 3;\r
30fdf114
LG
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
52302d4d 789 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);\r
30fdf114
LG
790 pHoursField->mOffset = 0;\r
791 pHoursField->mNext = pMinutesField;\r
792 pHoursField->mArrayNum = 0;\r
793\r
794 strcpy (pMinutesField->mFieldName, "Minutes");\r
52302d4d 795 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);\r
30fdf114
LG
796 pMinutesField->mOffset = 1;\r
797 pMinutesField->mNext = pSecondsField;\r
798 pMinutesField->mArrayNum = 0;\r
799\r
800 strcpy (pSecondsField->mFieldName, "Seconds");\r
52302d4d 801 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);\r
30fdf114
LG
802 pSecondsField->mOffset = 2;\r
803 pSecondsField->mNext = NULL;\r
804 pSecondsField->mArrayNum = 0;\r
805\r
806 New->mMembers = pHoursField;\r
4234283c
LG
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
30fdf114
LG
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
52302d4d 905 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);\r
30fdf114
LG
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
52302d4d 922 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");\r
30fdf114
LG
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
52302d4d 936 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
30fdf114
LG
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
52302d4d 1179 Offset = (UINT16) (Offset + Tmp);\r
30fdf114
LG
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
52302d4d 1438 Index = 0;\r
30fdf114
LG
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
da92f276
LG
1508 if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
1509 return VFR_RETURN_REDEFINED;\r
30fdf114
LG
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
da92f276
LG
1581 if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
1582 return VFR_RETURN_REDEFINED;\r
30fdf114
LG
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
da92f276 1608 EFI_VARSTORE_ID TempVarStoreId;\r
30fdf114
LG
1609\r
1610 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1611 return VFR_RETURN_FATAL_ERROR;\r
1612 }\r
1613\r
da92f276
LG
1614 if (GetVarStoreId (StoreName, &TempVarStoreId) == VFR_RETURN_SUCCESS) {\r
1615 return VFR_RETURN_REDEFINED;\r
1616 }\r
1617\r
30fdf114
LG
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
da92f276
LG
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
30fdf114
LG
1681EFI_VFR_RETURN_CODE \r
1682CVfrDataStorage::GetVarStoreId (\r
1683 IN CHAR8 *StoreName,\r
1684 OUT EFI_VARSTORE_ID *VarStoreId\r
1685 )\r
1686{\r
da92f276 1687 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114
LG
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
da92f276
LG
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
30fdf114
LG
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
da92f276 1736 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114
LG
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
da92f276
LG
1748 ReturnCode = VFR_RETURN_UNDEFINED;\r
1749 //\r
1750 // Assume that Data strucutre name is used as StoreName, and check again. \r
1751 //\r
30fdf114 1752 if (pNode == NULL) {\r
da92f276
LG
1753 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1754 }\r
1755\r
1756 if (pNode == NULL) {\r
1757 return ReturnCode;\r
30fdf114
LG
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
da92f276 1775 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114
LG
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
df1780f8 1782 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
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
df1780f8 1789 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
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
df1780f8 1796 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
1797 VarStoreType = pNode->mVarStoreType;\r
1798 return VFR_RETURN_SUCCESS;\r
1799 }\r
1800 }\r
1801\r
1802 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
da92f276
LG
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
30fdf114
LG
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
30fdf114
LG
1960 SVfrVarStorageNode *pNode = NULL;\r
1961 EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;\r
da92f276 1962 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114
LG
1963\r
1964 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
52302d4d 1965 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
30fdf114
LG
1966 break;\r
1967 }\r
1968 }\r
1969\r
da92f276
LG
1970 ReturnCode = VFR_RETURN_UNDEFINED;\r
1971 //\r
1972 // Assume that Data strucutre name is used as StoreName, and check again. \r
1973 //\r
30fdf114 1974 if (pNode == NULL) {\r
da92f276
LG
1975 ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
1976 }\r
1977\r
1978 if (pNode == NULL) {\r
1979 return ReturnCode;\r
30fdf114
LG
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
30fdf114
LG
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
52302d4d 2390 mQtype = QUESTION_NORMAL;\r
30fdf114
LG
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
52302d4d
LG
2560 pNode[0]->mQtype = QUESTION_DATE;\r
2561 pNode[1]->mQtype = QUESTION_DATE;\r
2562 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
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
52302d4d
LG
2639 pNode[0]->mQtype = QUESTION_DATE;\r
2640 pNode[1]->mQtype = QUESTION_DATE;\r
2641 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
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
52302d4d
LG
2708 pNode[0]->mQtype = QUESTION_TIME;\r
2709 pNode[1]->mQtype = QUESTION_TIME;\r
2710 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
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
52302d4d
LG
2787 pNode[0]->mQtype = QUESTION_TIME;\r
2788 pNode[1]->mQtype = QUESTION_TIME;\r
2789 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
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
4234283c
LG
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
30fdf114
LG
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
52302d4d
LG
2957 OUT UINT32 &BitMask,\r
2958 OUT EFI_QUESION_TYPE *QType\r
30fdf114
LG
2959 )\r
2960{\r
2961 SVfrQuestionNode *pNode;\r
2962\r
2963 QuestionId = EFI_QUESTION_ID_INVALID;\r
2964 BitMask = 0x00000000;\r
52302d4d
LG
2965 if (QType != NULL) {\r
2966 *QType = QUESTION_NORMAL;\r
2967 }\r
30fdf114
LG
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
52302d4d
LG
2988 if (QType != NULL) {\r
2989 *QType = pNode->mQtype;\r
2990 }\r
30fdf114
LG
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
4234283c
LG
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
64b2609f
LG
3070\r
3071/**\r
3072 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language \r
3073 from a set of supported languages.\r
3074\r
3075 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that\r
3076 contains a set of language codes.\r
3077 @param[in] Language A variable that contains pointers to Null-terminated\r
3078 ASCII strings that contain one language codes.\r
3079\r
3080 @retval FALSE The best matching language could not be found in SupportedLanguages.\r
3081 @retval TRUE The best matching language could be found in SupportedLanguages.\r
3082\r
3083**/\r
3084BOOLEAN\r
3085CVfrStringDB::GetBestLanguage (\r
3086 IN CONST CHAR8 *SupportedLanguages,\r
3087 IN CHAR8 *Language\r
3088 )\r
3089{\r
3090 UINTN CompareLength;\r
3091 UINTN LanguageLength;\r
3092 CONST CHAR8 *Supported;\r
3093\r
3094 if (SupportedLanguages == NULL || Language == NULL){\r
3095 return FALSE;\r
3096 }\r
3097\r
3098 //\r
3099 // Determine the length of the first RFC 4646 language code in Language\r
3100 //\r
3101 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
3102\r
3103 //\r
3104 // Trim back the length of Language used until it is empty\r
3105 //\r
3106 while (LanguageLength > 0) {\r
3107 //\r
3108 // Loop through all language codes in SupportedLanguages\r
3109 //\r
3110 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
3111 //\r
3112 // Skip ';' characters in Supported\r
3113 //\r
3114 for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
3115 //\r
3116 // Determine the length of the next language code in Supported\r
3117 //\r
3118 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
3119 //\r
3120 // If Language is longer than the Supported, then skip to the next language\r
3121 //\r
3122 if (LanguageLength > CompareLength) {\r
3123 continue;\r
3124 }\r
3125\r
3126 //\r
3127 // See if the first LanguageLength characters in Supported match Language\r
3128 //\r
3129 if (strncmp (Supported, Language, LanguageLength) == 0) {\r
3130 return TRUE;\r
3131 }\r
3132 }\r
3133\r
3134 //\r
3135 // Trim Language from the right to the next '-' character \r
3136 //\r
3137 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
3138 }\r
3139\r
3140 //\r
3141 // No matches were found \r
3142 //\r
3143 return FALSE;\r
3144}\r
3145\r
3146\r
4234283c
LG
3147CHAR8 *\r
3148CVfrStringDB::GetVarStoreNameFormStringId (\r
3149 IN EFI_STRING_ID StringId\r
3150 )\r
3151{\r
3152 FILE *pInFile = NULL;\r
3153 UINT32 NameOffset;\r
3154 UINT32 Length;\r
3155 UINT8 *StringPtr;\r
3156 CHAR8 *StringName;\r
3157 CHAR16 *UnicodeString;\r
3158 CHAR8 *VarStoreName = NULL;\r
3159 CHAR8 *DestTmp;\r
3160 UINT8 *Current;\r
3161 EFI_STATUS Status;\r
3162 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];\r
3163 UINT8 BlockType;\r
3164 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
3165 \r
3166 if (mStringFileName == '\0' ) {\r
3167 return NULL;\r
3168 }\r
3169\r
3170 if ((pInFile = fopen (mStringFileName, "rb")) == NULL) {\r
3171 return NULL;\r
3172 }\r
3173\r
3174 //\r
3175 // Get file length.\r
3176 //\r
3177 fseek (pInFile, 0, SEEK_END);\r
3178 Length = ftell (pInFile);\r
3179 fseek (pInFile, 0, SEEK_SET);\r
3180\r
3181 //\r
3182 // Get file data.\r
3183 //\r
3184 StringPtr = new UINT8[Length];\r
3185 if (StringPtr == NULL) {\r
3186 fclose (pInFile);\r
3187 return NULL;\r
3188 }\r
3189 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
3190 fclose (pInFile);\r
3191\r
3192 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
3193 //\r
3194 // Check the String package.\r
3195 //\r
3196 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
3197 delete StringPtr;\r
3198 return NULL;\r
3199 }\r
3200\r
3201 //\r
64b2609f 3202 // Search the language, get best language base on RFC 4647 matching algorithm.\r
4234283c
LG
3203 //\r
3204 Current = StringPtr;\r
64b2609f 3205 while (!GetBestLanguage ("en", PkgHeader->Language)) {\r
4234283c
LG
3206 Current += PkgHeader->Header.Length;\r
3207 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
3208 //\r
64b2609f 3209 // If can't find string package base on language, just return the first string package.\r
4234283c
LG
3210 //\r
3211 if (Current - StringPtr >= Length) {\r
3212 Current = StringPtr;\r
64b2609f 3213 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
4234283c
LG
3214 break;\r
3215 }\r
3216 }\r
3217\r
3218 Current += PkgHeader->HdrSize;\r
3219 //\r
3220 // Find the string block according the stringId.\r
3221 //\r
3222 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
3223 if (Status != EFI_SUCCESS) {\r
3224 delete StringPtr;\r
3225 return NULL;\r
3226 }\r
3227\r
3228 //\r
3229 // Get varstore name according the string type.\r
3230 //\r
3231 switch (BlockType) {\r
3232 case EFI_HII_SIBT_STRING_SCSU:\r
3233 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3234 case EFI_HII_SIBT_STRINGS_SCSU:\r
3235 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3236 StringName = (CHAR8*)(Current + NameOffset);\r
3237 VarStoreName = new CHAR8[strlen(StringName) + 1];\r
3238 strcpy (VarStoreName, StringName);\r
3239 break;\r
3240 case EFI_HII_SIBT_STRING_UCS2:\r
3241 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3242 case EFI_HII_SIBT_STRINGS_UCS2:\r
3243 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3244 UnicodeString = (CHAR16*)(Current + NameOffset);\r
3245 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
3246 DestTmp = new CHAR8[Length / 2 + 1];\r
3247 VarStoreName = DestTmp;\r
3248 while (*UnicodeString != '\0') {\r
3249 *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
3250 }\r
3251 *DestTmp = '\0';\r
3252 break;\r
3253 default:\r
3254 break;\r
3255 }\r
3256\r
3257 delete StringPtr;\r
3258\r
3259 return VarStoreName;\r
3260}\r
3261\r
3262EFI_STATUS\r
3263CVfrStringDB::FindStringBlock (\r
3264 IN UINT8 *StringData,\r
3265 IN EFI_STRING_ID StringId,\r
3266 OUT UINT32 *StringTextOffset,\r
3267 OUT UINT8 *BlockType\r
3268 )\r
3269{\r
3270 UINT8 *BlockHdr;\r
3271 EFI_STRING_ID CurrentStringId;\r
3272 UINT32 BlockSize;\r
3273 UINT32 Index;\r
3274 UINT8 *StringTextPtr;\r
3275 UINT32 Offset;\r
3276 UINT16 StringCount;\r
3277 UINT16 SkipCount;\r
3278 UINT8 Length8;\r
3279 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
3280 UINT32 Length32;\r
3281 UINT32 StringSize;\r
3282\r
3283 CurrentStringId = 1;\r
3284\r
3285 //\r
3286 // Parse the string blocks to get the string text and font.\r
3287 //\r
3288 BlockHdr = StringData;\r
3289 BlockSize = 0;\r
3290 Offset = 0;\r
3291 while (*BlockHdr != EFI_HII_SIBT_END) {\r
3292 switch (*BlockHdr) {\r
3293 case EFI_HII_SIBT_STRING_SCSU:\r
3294 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3295 StringTextPtr = BlockHdr + Offset;\r
3296 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3297 CurrentStringId++;\r
3298 break;\r
3299\r
3300 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3301 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3302 StringTextPtr = BlockHdr + Offset;\r
3303 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3304 CurrentStringId++;\r
3305 break;\r
3306\r
3307 case EFI_HII_SIBT_STRINGS_SCSU:\r
3308 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3309 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
3310 BlockSize += StringTextPtr - BlockHdr;\r
3311\r
3312 for (Index = 0; Index < StringCount; Index++) {\r
3313 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3314 if (CurrentStringId == StringId) {\r
3315 *BlockType = *BlockHdr;\r
3316 *StringTextOffset = StringTextPtr - StringData;\r
3317 return EFI_SUCCESS;\r
3318 }\r
3319 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3320 CurrentStringId++;\r
3321 }\r
3322 break;\r
3323\r
3324 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3325 memcpy (\r
3326 &StringCount,\r
3327 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3328 sizeof (UINT16)\r
3329 );\r
3330 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3331 BlockSize += StringTextPtr - BlockHdr;\r
3332\r
3333 for (Index = 0; Index < StringCount; Index++) {\r
3334 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3335 if (CurrentStringId == StringId) {\r
3336 *BlockType = *BlockHdr;\r
3337 *StringTextOffset = StringTextPtr - StringData;\r
3338 return EFI_SUCCESS;\r
3339 }\r
3340 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3341 CurrentStringId++;\r
3342 }\r
3343 break;\r
3344\r
3345 case EFI_HII_SIBT_STRING_UCS2:\r
3346 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3347 StringTextPtr = BlockHdr + Offset;\r
3348 //\r
3349 // Use StringSize to store the size of the specified string, including the NULL\r
3350 // terminator.\r
3351 //\r
3352 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3353 BlockSize += Offset + StringSize;\r
3354 CurrentStringId++;\r
3355 break;\r
3356\r
3357 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3358 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3359 StringTextPtr = BlockHdr + Offset;\r
3360 //\r
3361 // Use StrSize to store the size of the specified string, including the NULL\r
3362 // terminator.\r
3363 //\r
3364 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3365 BlockSize += Offset + StringSize;\r
3366 CurrentStringId++;\r
3367 break;\r
3368\r
3369 case EFI_HII_SIBT_STRINGS_UCS2:\r
3370 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
3371 StringTextPtr = BlockHdr + Offset;\r
3372 BlockSize += Offset;\r
3373 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3374 for (Index = 0; Index < StringCount; Index++) {\r
3375 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3376 BlockSize += StringSize;\r
3377 if (CurrentStringId == StringId) {\r
3378 *BlockType = *BlockHdr;\r
3379 *StringTextOffset = StringTextPtr - StringData;\r
3380 return EFI_SUCCESS;\r
3381 }\r
3382 StringTextPtr = StringTextPtr + StringSize;\r
3383 CurrentStringId++;\r
3384 }\r
3385 break;\r
3386\r
3387 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3388 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3389 StringTextPtr = BlockHdr + Offset;\r
3390 BlockSize += Offset;\r
3391 memcpy (\r
3392 &StringCount,\r
3393 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3394 sizeof (UINT16)\r
3395 );\r
3396 for (Index = 0; Index < StringCount; Index++) {\r
3397 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3398 BlockSize += StringSize;\r
3399 if (CurrentStringId == StringId) {\r
3400 *BlockType = *BlockHdr;\r
3401 *StringTextOffset = StringTextPtr - StringData;\r
3402 return EFI_SUCCESS;\r
3403 }\r
3404 StringTextPtr = StringTextPtr + StringSize;\r
3405 CurrentStringId++;\r
3406 }\r
3407 break;\r
3408\r
3409 case EFI_HII_SIBT_DUPLICATE:\r
3410 if (CurrentStringId == StringId) {\r
3411 //\r
3412 // Incoming StringId is an id of a duplicate string block.\r
3413 // Update the StringId to be the previous string block.\r
3414 // Go back to the header of string block to search.\r
3415 //\r
3416 memcpy (\r
3417 &StringId,\r
3418 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
3419 sizeof (EFI_STRING_ID)\r
3420 );\r
3421 CurrentStringId = 1;\r
3422 BlockSize = 0;\r
3423 } else {\r
3424 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
3425 CurrentStringId++;\r
3426 }\r
3427 break;\r
3428\r
3429 case EFI_HII_SIBT_SKIP1:\r
3430 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
3431 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3432 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
3433 break;\r
3434\r
3435 case EFI_HII_SIBT_SKIP2:\r
3436 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3437 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3438 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
3439 break;\r
3440\r
3441 case EFI_HII_SIBT_EXT1:\r
3442 memcpy (\r
3443 &Length8,\r
3444 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3445 sizeof (UINT8)\r
3446 );\r
3447 BlockSize += Length8;\r
3448 break;\r
3449\r
3450 case EFI_HII_SIBT_EXT2:\r
3451 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
3452 BlockSize += Ext2.Length;\r
3453 break;\r
3454\r
3455 case EFI_HII_SIBT_EXT4:\r
3456 memcpy (\r
3457 &Length32,\r
3458 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3459 sizeof (UINT32)\r
3460 );\r
3461\r
3462 BlockSize += Length32;\r
3463 break;\r
3464\r
3465 default:\r
3466 break;\r
3467 }\r
3468\r
3469 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
3470 *StringTextOffset = BlockHdr - StringData + Offset;\r
3471 *BlockType = *BlockHdr;\r
3472\r
3473 if (StringId == CurrentStringId - 1) {\r
3474 //\r
3475 // if only one skip item, return EFI_NOT_FOUND.\r
3476 //\r
3477 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
3478 return EFI_NOT_FOUND;\r
3479 } else {\r
3480 return EFI_SUCCESS;\r
3481 }\r
3482 }\r
3483\r
3484 if (StringId < CurrentStringId - 1) {\r
3485 return EFI_NOT_FOUND;\r
3486 }\r
3487 }\r
3488 BlockHdr = StringData + BlockSize;\r
3489 }\r
3490\r
3491 return EFI_NOT_FOUND;\r
3492}\r
3493\r
3494UINT32\r
3495CVfrStringDB::GetUnicodeStringTextSize (\r
3496 IN UINT8 *StringSrc\r
3497 )\r
3498{\r
3499 UINT32 StringSize;\r
3500 CHAR16 *StringPtr;\r
3501\r
3502 StringSize = sizeof (CHAR16);\r
3503 StringPtr = (UINT16*)StringSrc;\r
3504 while (*StringPtr++ != L'\0') {\r
3505 StringSize += sizeof (CHAR16);\r
3506 }\r
3507\r
3508 return StringSize;\r
3509}\r
3510\r
30fdf114
LG
3511BOOLEAN VfrCompatibleMode = FALSE;\r
3512\r
3513CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
3514\r
52302d4d 3515\r