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