]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools/VfrCompile: Add/refine boundary checks for strcpy/strcat
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 Vfr common library functions.\r
4\r
2b7f3d4a 5Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "stdlib.h"\r
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
75 IN UINT8 Type, \r
76 IN UINT16 Offset, \r
77 IN UINT32 Width, \r
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
363 delete mItemListPos->mId;\r
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
556 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
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
767 \r
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
782 \r
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
961\r
962 InternalTypesListInit ();\r
963}\r
964\r
965CVfrVarDataTypeDB::~CVfrVarDataTypeDB (\r
966 VOID\r
967 )\r
968{\r
969 SVfrDataType *pType;\r
970 SVfrDataField *pField;\r
971 SVfrPackStackNode *pPack;\r
972\r
973 if (mNewDataType != NULL) {\r
974 delete mNewDataType;\r
975 }\r
976\r
977 while (mDataTypeList != NULL) {\r
978 pType = mDataTypeList;\r
979 mDataTypeList = mDataTypeList->mNext;\r
980 while(pType->mMembers != NULL) {\r
981 pField = pType->mMembers;\r
982 pType->mMembers = pType->mMembers->mNext;\r
983 delete pField;\r
984 }\r
985 delete pType;\r
986 }\r
987\r
988 while (mPackStack != NULL) {\r
989 pPack = mPackStack;\r
990 mPackStack = mPackStack->mNext;\r
991 delete pPack;\r
992 }\r
993}\r
994\r
995EFI_VFR_RETURN_CODE\r
996CVfrVarDataTypeDB::Pack (\r
997 IN UINT32 LineNum,\r
998 IN UINT8 Action,\r
999 IN CHAR8 *Identifier,\r
1000 IN UINT32 Number\r
1001 )\r
1002{\r
1003 UINT32 PackAlign;\r
1004 CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
1005\r
1006 if (Action & VFR_PACK_SHOW) {\r
1007 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
52302d4d 1008 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);\r
30fdf114
LG
1009 }\r
1010\r
1011 if (Action & VFR_PACK_PUSH) {\r
1012 SVfrPackStackNode *pNew = NULL;\r
1013\r
1014 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {\r
1015 return VFR_RETURN_FATAL_ERROR;\r
1016 }\r
1017 pNew->mNext = mPackStack;\r
1018 mPackStack = pNew;\r
1019 }\r
1020\r
1021 if (Action & VFR_PACK_POP) {\r
1022 SVfrPackStackNode *pNode = NULL;\r
1023\r
1024 if (mPackStack == NULL) {\r
52302d4d 1025 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");\r
30fdf114
LG
1026 }\r
1027\r
1028 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
1029 if (pNode->Match (Identifier) == TRUE) {\r
1030 mPackAlign = pNode->mNumber;\r
1031 mPackStack = pNode->mNext;\r
1032 }\r
1033 }\r
1034 }\r
1035\r
1036 if (Action & VFR_PACK_ASSIGN) {\r
1037 PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
1038 if ((PackAlign == 0) || (PackAlign > 16)) {\r
52302d4d 1039 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
30fdf114
LG
1040 } else {\r
1041 mPackAlign = PackAlign;\r
1042 }\r
1043 }\r
1044\r
1045 return VFR_RETURN_SUCCESS;\r
1046}\r
1047\r
1048VOID\r
1049CVfrVarDataTypeDB::DeclareDataTypeBegin (\r
1050 VOID\r
1051 )\r
1052{\r
1053 SVfrDataType *pNewType = NULL;\r
1054\r
1055 pNewType = new SVfrDataType;\r
1056 pNewType->mTypeName[0] = '\0';\r
1057 pNewType->mType = EFI_IFR_TYPE_OTHER;\r
1058 pNewType->mAlign = DEFAULT_ALIGN;\r
1059 pNewType->mTotalSize = 0;\r
1060 pNewType->mMembers = NULL;\r
1061 pNewType->mNext = NULL;\r
42c808d4 1062 pNewType->mHasBitField = FALSE;\r
30fdf114
LG
1063\r
1064 mNewDataType = pNewType;\r
1065}\r
1066\r
1067EFI_VFR_RETURN_CODE\r
1068CVfrVarDataTypeDB::SetNewTypeName (\r
1069 IN CHAR8 *TypeName\r
1070 )\r
1071{\r
1072 SVfrDataType *pType;\r
1073\r
1074 if (mNewDataType == NULL) {\r
1075 return VFR_RETURN_ERROR_SKIPED;\r
1076 }\r
1077 if (TypeName == NULL) {\r
1078 return VFR_RETURN_FATAL_ERROR;\r
1079 }\r
1080 if (strlen(TypeName) >= MAX_NAME_LEN) {\r
1081 return VFR_RETURN_INVALID_PARAMETER;\r
1082 }\r
1083\r
1084 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1085 if (strcmp(pType->mTypeName, TypeName) == 0) {\r
1086 return VFR_RETURN_REDEFINED;\r
1087 }\r
1088 }\r
1089\r
d837f33a
HW
1090 strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);\r
1091 mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;\r
30fdf114
LG
1092 return VFR_RETURN_SUCCESS;\r
1093}\r
1094\r
42c808d4
DB
1095/**\r
1096 Record the bit field info in the data type.\r
1097\r
1098 @param FieldName Point to the field name.\r
1099 @param TypeName Point to the type name.\r
1100 @param Width The bit width.\r
1101 @param FieldInUnion The filed is in Union type or Structure type.\r
1102\r
1103**/\r
1104EFI_VFR_RETURN_CODE\r
1105CVfrVarDataTypeDB::DataTypeAddBitField (\r
1106 IN CHAR8 *FieldName,\r
1107 IN CHAR8 *TypeName,\r
1108 IN UINT32 Width,\r
1109 IN BOOLEAN FieldInUnion\r
1110 )\r
1111{\r
1112 SVfrDataField *pNewField = NULL;\r
1113 SVfrDataType *pFieldType = NULL;\r
1114 SVfrDataField *pTmp;\r
1115 UINT32 Align;\r
1116 UINT32 MaxDataTypeSize;\r
1117 BOOLEAN UpdateTotalSize;\r
1118\r
1119 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
1120\r
1121 if (Width > MAX_BIT_WIDTH) {\r
1122 return VFR_RETURN_BIT_WIDTH_ERROR;\r
1123 }\r
1124\r
1125 if (Width > pFieldType->mTotalSize * 8) {\r
1126 return VFR_RETURN_BIT_WIDTH_ERROR;\r
1127 }\r
1128\r
1129 if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {\r
1130 return VFR_RETURN_INVALID_PARAMETER;\r
1131 }\r
1132\r
1133 if (Width == 0 && FieldName != NULL) {\r
1134 return VFR_RETURN_INVALID_PARAMETER;\r
1135 }\r
1136\r
1137 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
1138 if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {\r
1139 return VFR_RETURN_REDEFINED;\r
1140 }\r
1141 }\r
1142\r
1143 Align = MIN (mPackAlign, pFieldType->mAlign);\r
1144 UpdateTotalSize = FALSE;\r
1145\r
1146 if ((pNewField = new SVfrDataField) == NULL) {\r
1147 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1148 }\r
1149\r
1150 MaxDataTypeSize = mNewDataType->mTotalSize;\r
1151 if (FieldName != NULL) {\r
d837f33a
HW
1152 strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
1153 pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
42c808d4
DB
1154 }\r
1155 pNewField->mFieldType = pFieldType;\r
1156 pNewField->mIsBitField = TRUE;\r
1157 pNewField->mBitWidth = Width;\r
1158 pNewField->mArrayNum = 0;\r
1159 pNewField->mBitOffset = 0;\r
1160 pNewField->mOffset = 0;\r
1161\r
1162 if (mNewDataType->mMembers == NULL) {\r
1163 mNewDataType->mMembers = pNewField;\r
1164 pNewField->mNext = NULL;\r
1165 } else {\r
1166 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
1167 ;\r
1168 pTmp->mNext = pNewField;\r
1169 pNewField->mNext = NULL;\r
1170 }\r
1171\r
1172 if (FieldInUnion) {\r
1173 pNewField->mOffset = 0;\r
1174 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
1175 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
1176 }\r
1177 } else {\r
1178 //\r
1179 // Check whether the bit fileds can be contained within one FieldType.\r
1180 //\r
1181 if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&\r
1182 (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {\r
1183 pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;\r
1184 pNewField->mOffset = pTmp->mOffset;\r
1185 //\r
1186 // If BitWidth=0,used to force alignment at the next word boundary.\r
1187 // So make this bit field occupy the remaing bit width of current field type.\r
1188 //\r
1189 if (pNewField->mBitWidth == 0) {\r
1190 pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);\r
1191 }\r
1192 } else {\r
1193 //\r
1194 // The bit filed start a new memory\r
1195 //\r
1196 pNewField->mBitOffset = mNewDataType->mTotalSize * 8;\r
1197 UpdateTotalSize = TRUE;\r
1198 }\r
1199 }\r
1200\r
1201 if (UpdateTotalSize){\r
1202 if ((mNewDataType->mTotalSize % Align) == 0) {\r
1203 pNewField->mOffset = mNewDataType->mTotalSize;\r
1204 } else {\r
1205 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
1206 }\r
1207 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);\r
1208 }\r
1209\r
1210 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
1211 mNewDataType->mHasBitField = TRUE;\r
1212 return VFR_RETURN_SUCCESS;\r
1213}\r
1214\r
30fdf114
LG
1215EFI_VFR_RETURN_CODE\r
1216CVfrVarDataTypeDB::DataTypeAddField (\r
1217 IN CHAR8 *FieldName,\r
1218 IN CHAR8 *TypeName,\r
2b7f3d4a
DB
1219 IN UINT32 ArrayNum,\r
1220 IN BOOLEAN FieldInUnion\r
30fdf114
LG
1221 )\r
1222{\r
1223 SVfrDataField *pNewField = NULL;\r
1224 SVfrDataType *pFieldType = NULL;\r
1225 SVfrDataField *pTmp;\r
1226 UINT32 Align;\r
2b7f3d4a 1227 UINT32 MaxDataTypeSize;\r
30fdf114
LG
1228\r
1229 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
2b7f3d4a 1230 MaxDataTypeSize = mNewDataType->mTotalSize;\r
30fdf114
LG
1231\r
1232 if (strlen (FieldName) >= MAX_NAME_LEN) {\r
1233 return VFR_RETURN_INVALID_PARAMETER;\r
1234 }\r
1235\r
1236 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
1237 if (strcmp (pTmp->mFieldName, FieldName) == 0) {\r
1238 return VFR_RETURN_REDEFINED;\r
1239 }\r
1240 }\r
1241\r
1242 Align = MIN (mPackAlign, pFieldType->mAlign);\r
1243\r
1244 if ((pNewField = new SVfrDataField) == NULL) {\r
1245 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1246 }\r
d837f33a
HW
1247 strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
1248 pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
30fdf114
LG
1249 pNewField->mFieldType = pFieldType;\r
1250 pNewField->mArrayNum = ArrayNum;\r
42c808d4 1251 pNewField->mIsBitField = FALSE;\r
30fdf114
LG
1252 if ((mNewDataType->mTotalSize % Align) == 0) {\r
1253 pNewField->mOffset = mNewDataType->mTotalSize;\r
1254 } else {\r
1255 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
1256 }\r
1257 if (mNewDataType->mMembers == NULL) {\r
1258 mNewDataType->mMembers = pNewField;\r
1259 pNewField->mNext = NULL;\r
1260 } else {\r
1261 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
1262 ;\r
1263 pTmp->mNext = pNewField;\r
1264 pNewField->mNext = NULL;\r
1265 }\r
1266\r
1267 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
2b7f3d4a
DB
1268\r
1269 if (FieldInUnion) {\r
1270 if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
1271 mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
1272 }\r
1273 pNewField->mOffset = 0;\r
1274 } else {\r
1275 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
1276 }\r
30fdf114
LG
1277\r
1278 return VFR_RETURN_SUCCESS;\r
1279}\r
1280\r
1281VOID\r
1282CVfrVarDataTypeDB::DeclareDataTypeEnd (\r
1283 VOID\r
1284 )\r
1285{\r
1286 if (mNewDataType->mTypeName[0] == '\0') {\r
1287 return;\r
1288 }\r
1289\r
1290 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {\r
1291 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);\r
1292 }\r
1293\r
1294 RegisterNewType (mNewDataType);\r
1295 if (mFirstNewDataTypeName == NULL) {\r
1296 mFirstNewDataTypeName = mNewDataType->mTypeName;\r
1297 }\r
1298\r
1299 mNewDataType = NULL;\r
1300}\r
1301\r
1302EFI_VFR_RETURN_CODE\r
1303CVfrVarDataTypeDB::GetDataType (\r
1304 IN CHAR8 *TypeName,\r
1305 OUT SVfrDataType **DataType\r
1306 )\r
1307{\r
1308 SVfrDataType *pDataType = NULL;\r
1309\r
1310 if (TypeName == NULL) {\r
1311 return VFR_RETURN_ERROR_SKIPED;\r
1312 }\r
1313\r
1314 if (DataType == NULL) {\r
1315 return VFR_RETURN_FATAL_ERROR;\r
1316 }\r
1317\r
1318 *DataType = NULL;\r
1319\r
1320 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1321 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1322 *DataType = pDataType;\r
1323 return VFR_RETURN_SUCCESS;\r
1324 }\r
1325 }\r
1326\r
1327 return VFR_RETURN_UNDEFINED;\r
1328}\r
1329\r
1330EFI_VFR_RETURN_CODE\r
1331CVfrVarDataTypeDB::GetDataTypeSize (\r
1332 IN UINT8 DataType,\r
1333 OUT UINT32 *Size\r
1334 )\r
1335{\r
1336 SVfrDataType *pDataType = NULL;\r
1337\r
1338 if (Size == NULL) {\r
1339 return VFR_RETURN_FATAL_ERROR;\r
1340 }\r
1341\r
1342 *Size = 0;\r
1343 DataType = DataType & 0x0F;\r
1344\r
1345 //\r
1346 // For user defined data type, the size can't be got by this function.\r
1347 //\r
1348 if (DataType == EFI_IFR_TYPE_OTHER) {\r
1349 return VFR_RETURN_SUCCESS;\r
1350 }\r
1351\r
1352 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1353 if (DataType == pDataType->mType) {\r
1354 *Size = pDataType->mTotalSize;\r
1355 return VFR_RETURN_SUCCESS;\r
1356 }\r
1357 }\r
1358\r
1359 return VFR_RETURN_UNDEFINED;\r
1360}\r
1361\r
1362EFI_VFR_RETURN_CODE\r
1363CVfrVarDataTypeDB::GetDataTypeSize (\r
1364 IN CHAR8 *TypeName,\r
1365 OUT UINT32 *Size\r
1366 )\r
1367{\r
1368 SVfrDataType *pDataType = NULL;\r
1369\r
1370 if (Size == NULL) {\r
1371 return VFR_RETURN_FATAL_ERROR;\r
1372 }\r
1373\r
1374 *Size = 0;\r
1375\r
1376 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1377 if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1378 *Size = pDataType->mTotalSize;\r
1379 return VFR_RETURN_SUCCESS;\r
1380 }\r
1381 }\r
1382\r
1383 return VFR_RETURN_UNDEFINED;\r
1384}\r
1385\r
1386EFI_VFR_RETURN_CODE\r
1387CVfrVarDataTypeDB::GetDataFieldInfo (\r
1388 IN CHAR8 *VarStr,\r
1389 OUT UINT16 &Offset,\r
1390 OUT UINT8 &Type,\r
42c808d4
DB
1391 OUT UINT32 &Size,\r
1392 OUT BOOLEAN &BitField\r
30fdf114
LG
1393 )\r
1394{\r
1395 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
1396 UINT32 ArrayIdx, Tmp;\r
1397 SVfrDataType *pType = NULL;\r
1398 SVfrDataField *pField = NULL;\r
42c808d4 1399 CHAR8 *VarStrName;\r
30fdf114
LG
1400\r
1401 Offset = 0;\r
1402 Type = EFI_IFR_TYPE_OTHER;\r
1403 Size = 0;\r
42c808d4 1404 VarStrName = VarStr;\r
30fdf114
LG
1405\r
1406 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
1407 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
1408\r
42c808d4
DB
1409 BitField = IsThisBitField (VarStrName);\r
1410\r
30fdf114
LG
1411 //\r
1412 // if it is not struct data type\r
1413 //\r
1414 Type = pType->mType;\r
1415 Size = pType->mTotalSize;\r
1416\r
1417 while (*VarStr != '\0') {\r
42c808d4 1418 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
30fdf114
LG
1419 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
1420 pType = pField->mFieldType;\r
42c808d4
DB
1421 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);\r
1422 if (BitField && !pField->mIsBitField) {\r
1423 Offset = (UINT16) (Offset + Tmp * 8);\r
1424 } else {\r
1425 Offset = (UINT16) (Offset + Tmp);\r
1426 }\r
30fdf114 1427 Type = GetFieldWidth (pField);\r
42c808d4 1428 Size = GetFieldSize (pField, ArrayIdx, BitField);\r
30fdf114
LG
1429 }\r
1430 return VFR_RETURN_SUCCESS;\r
1431}\r
1432\r
1433EFI_VFR_RETURN_CODE\r
1434CVfrVarDataTypeDB::GetUserDefinedTypeNameList (\r
1435 OUT CHAR8 ***NameList,\r
1436 OUT UINT32 *ListSize\r
1437 )\r
1438{\r
1439 UINT32 Index;\r
1440 SVfrDataType *pType;\r
1441\r
1442 if ((NameList == NULL) || (ListSize == NULL)) {\r
1443 return VFR_RETURN_FATAL_ERROR;\r
1444 }\r
1445\r
1446 *NameList = NULL;\r
1447 *ListSize = 0;\r
1448\r
1449 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1450 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1451 (*ListSize)++;\r
1452 }\r
1453 }\r
1454\r
1455 if (*ListSize == 0) {\r
1456 return VFR_RETURN_SUCCESS;\r
1457 }\r
1458\r
1459 if ((*NameList = new CHAR8*[*ListSize]) == NULL) {\r
1460 *ListSize = 0;\r
1461 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1462 }\r
1463\r
1464 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {\r
1465 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1466 (*NameList)[Index] = pType->mTypeName;\r
1467 }\r
1468 }\r
1469 return VFR_RETURN_SUCCESS;\r
1470}\r
1471\r
1472BOOLEAN\r
1473CVfrVarDataTypeDB::IsTypeNameDefined (\r
1474 IN CHAR8 *TypeName\r
1475 )\r
1476{\r
1477 SVfrDataType *pType;\r
1478\r
1479 if (TypeName == NULL) {\r
1480 return FALSE;\r
1481 }\r
1482\r
1483 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1484 if (strcmp (pType->mTypeName, TypeName) == 0) {\r
1485 return TRUE;\r
1486 }\r
1487 }\r
1488\r
1489 return FALSE;\r
1490}\r
1491\r
1492VOID\r
1493CVfrVarDataTypeDB::Dump (\r
1494 IN FILE *File\r
1495 )\r
1496{\r
1497 SVfrDataType *pTNode;\r
1498 SVfrDataField *pFNode;\r
1499\r
1500 fprintf (File, "\n\n***************************************************************\n");\r
1501 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);\r
1502 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1503 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1504 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);\r
1505 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1506 if (pFNode->mArrayNum > 0) {\r
1507 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1508 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);\r
1509 } else {\r
1510 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
1511 pFNode->mFieldName, pFNode->mFieldType->mTypeName);\r
1512 }\r
1513 }\r
1514 fprintf (File, "\t\t};\n");\r
1515 fprintf (File, "---------------------------------------------------------------\n");\r
1516 }\r
1517 fprintf (File, "***************************************************************\n");\r
1518}\r
1519\r
1520#ifdef CVFR_VARDATATYPEDB_DEBUG\r
1521VOID\r
1522CVfrVarDataTypeDB::ParserDB (\r
1523 VOID\r
1524 )\r
1525{\r
1526 SVfrDataType *pTNode;\r
1527 SVfrDataField *pFNode;\r
1528\r
1529 printf ("***************************************************************\n");\r
1530 printf ("\t\tmPackAlign = %x\n", mPackAlign);\r
1531 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1532 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1533 printf ("\t\tstruct %s {\n", pTNode->mTypeName);\r
1534 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1535 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
1536 }\r
1537 printf ("\t\t};\n");\r
1538 printf ("---------------------------------------------------------------\n");\r
1539 }\r
1540 printf ("***************************************************************\n");\r
1541}\r
1542#endif\r
1543\r
1544SVfrVarStorageNode::SVfrVarStorageNode (\r
1545 IN EFI_GUID *Guid,\r
1546 IN CHAR8 *StoreName,\r
1547 IN EFI_VARSTORE_ID VarStoreId,\r
1548 IN EFI_STRING_ID VarName,\r
1549 IN UINT32 VarSize,\r
1550 IN BOOLEAN Flag\r
1551 )\r
1552{\r
1553 if (Guid != NULL) {\r
1554 mGuid = *Guid;\r
1555 } else {\r
61eb9834 1556 memset (&mGuid, 0, sizeof (EFI_GUID));\r
30fdf114
LG
1557 }\r
1558 if (StoreName != NULL) {\r
1559 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1560 strcpy (mVarStoreName, StoreName);\r
1561 } else {\r
1562 mVarStoreName = NULL;\r
1563 }\r
1564 mNext = NULL;\r
1565 mVarStoreId = VarStoreId;\r
1566 mVarStoreType = EFI_VFR_VARSTORE_EFI;\r
1567 mStorageInfo.mEfiVar.mEfiVarName = VarName;\r
1568 mStorageInfo.mEfiVar.mEfiVarSize = VarSize;\r
1569 mAssignedFlag = Flag;\r
1570}\r
1571\r
1572SVfrVarStorageNode::SVfrVarStorageNode (\r
1573 IN EFI_GUID *Guid,\r
1574 IN CHAR8 *StoreName,\r
1575 IN EFI_VARSTORE_ID VarStoreId,\r
1576 IN SVfrDataType *DataType,\r
42c808d4 1577 IN BOOLEAN BitsVarstore,\r
30fdf114
LG
1578 IN BOOLEAN Flag\r
1579 )\r
1580{\r
1581 if (Guid != NULL) {\r
1582 mGuid = *Guid;\r
1583 } else {\r
61eb9834 1584 memset (&mGuid, 0, sizeof (EFI_GUID));\r
30fdf114
LG
1585 }\r
1586 if (StoreName != NULL) {\r
1587 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1588 strcpy (mVarStoreName, StoreName);\r
1589 } else {\r
1590 mVarStoreName = NULL;\r
1591 }\r
1592 mNext = NULL;\r
1593 mVarStoreId = VarStoreId;\r
42c808d4
DB
1594 if (BitsVarstore) {\r
1595 mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;\r
1596 } else {\r
1597 mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
1598 }\r
30fdf114
LG
1599 mStorageInfo.mDataType = DataType;\r
1600 mAssignedFlag = Flag;\r
1601}\r
1602\r
1603SVfrVarStorageNode::SVfrVarStorageNode (\r
1604 IN CHAR8 *StoreName,\r
1605 IN EFI_VARSTORE_ID VarStoreId\r
1606 )\r
1607{\r
1608 if (StoreName != NULL) {\r
1609 mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1610 strcpy (mVarStoreName, StoreName);\r
1611 } else {\r
1612 mVarStoreName = NULL;\r
1613 }\r
1614 mNext = NULL;\r
1615 mVarStoreId = VarStoreId;\r
1616 mVarStoreType = EFI_VFR_VARSTORE_NAME;\r
1617 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
1618 mStorageInfo.mNameSpace.mTableSize = 0;\r
1619}\r
1620\r
1621SVfrVarStorageNode::~SVfrVarStorageNode (\r
1622 VOID\r
1623 )\r
1624{\r
1625 if (mVarStoreName != NULL) {\r
fd542523 1626 delete[] mVarStoreName;\r
30fdf114
LG
1627 }\r
1628\r
1629 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
1630 delete mStorageInfo.mNameSpace.mNameTable;\r
1631 }\r
1632}\r
1633\r
1634CVfrDataStorage::CVfrDataStorage (\r
1635 VOID\r
1636 )\r
1637{\r
1638 UINT32 Index;\r
1639\r
1640 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1641 mFreeVarStoreIdBitMap[Index] = 0;\r
1642 }\r
1643\r
1644 // Question ID 0 is reserved.\r
1645 mFreeVarStoreIdBitMap[0] = 0x80000000;\r
1646\r
1647 mBufferVarStoreList = NULL;\r
1648 mEfiVarStoreList = NULL;\r
1649 mNameVarStoreList = NULL;\r
1650 mCurrVarStorageNode = NULL;\r
1651 mNewVarStorageNode = NULL;\r
74bbe31b
DB
1652 mBufferFieldInfoListHead = NULL;\r
1653 mBufferFieldInfoListTail = NULL;\r
30fdf114
LG
1654}\r
1655\r
1656CVfrDataStorage::~CVfrDataStorage (\r
1657 VOID\r
1658 )\r
1659{\r
1660 SVfrVarStorageNode *pNode;\r
1661\r
1662 while (mBufferVarStoreList != NULL) {\r
1663 pNode = mBufferVarStoreList;\r
1664 mBufferVarStoreList = mBufferVarStoreList->mNext;\r
1665 delete pNode;\r
1666 }\r
1667 while (mEfiVarStoreList != NULL) {\r
1668 pNode = mEfiVarStoreList;\r
1669 mEfiVarStoreList = mEfiVarStoreList->mNext;\r
1670 delete pNode;\r
1671 }\r
1672 while (mNameVarStoreList != NULL) {\r
1673 pNode = mNameVarStoreList;\r
1674 mNameVarStoreList = mNameVarStoreList->mNext;\r
1675 delete pNode;\r
1676 }\r
1677 if (mNewVarStorageNode != NULL) {\r
1678 delete mNewVarStorageNode;\r
1679 }\r
1680}\r
1681\r
1682EFI_VARSTORE_ID\r
1683CVfrDataStorage::GetFreeVarStoreId (\r
1684 EFI_VFR_VARSTORE_TYPE VarType\r
1685 )\r
1686{\r
1687 UINT32 Index, Mask, Offset;\r
1688 \r
1689 //\r
1690 // Assign the different ID range for the different type VarStore to support Framework Vfr\r
1691 //\r
52302d4d 1692 Index = 0;\r
30fdf114
LG
1693 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {\r
1694 Index = 0;\r
1695 } else if (VarType == EFI_VFR_VARSTORE_EFI) {\r
1696 Index = 1;\r
1697 } else if (VarType == EFI_VFR_VARSTORE_NAME) {\r
1698 Index = 2;\r
1699 }\r
1700\r
1701 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1702 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {\r
1703 break;\r
1704 }\r
1705 }\r
1706\r
bab5ad2f
HW
1707 if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {\r
1708 return EFI_VARSTORE_ID_INVALID;\r
1709 }\r
1710\r
30fdf114
LG
1711 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
1712 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
1713 mFreeVarStoreIdBitMap[Index] |= Mask;\r
1714 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
1715 }\r
1716 }\r
1717\r
1718 return EFI_VARSTORE_ID_INVALID;\r
1719}\r
1720\r
1721BOOLEAN\r
1722CVfrDataStorage::ChekVarStoreIdFree (\r
1723 IN EFI_VARSTORE_ID VarStoreId\r
1724 )\r
1725{\r
1726 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1727 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1728\r
1729 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
1730}\r
1731\r
1732VOID\r
1733CVfrDataStorage::MarkVarStoreIdUsed (\r
1734 IN EFI_VARSTORE_ID VarStoreId\r
1735 )\r
1736{\r
1737 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1738 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1739\r
1740 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
1741}\r
1742\r
1743VOID\r
1744CVfrDataStorage::MarkVarStoreIdUnused (\r
1745 IN EFI_VARSTORE_ID VarStoreId\r
1746 )\r
1747{\r
1748 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1749 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1750\r
1751 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
1752}\r
1753\r
1754EFI_VFR_RETURN_CODE\r
1755CVfrDataStorage::DeclareNameVarStoreBegin (\r
e8a47801
LG
1756 IN CHAR8 *StoreName,\r
1757 IN EFI_VARSTORE_ID VarStoreId\r
30fdf114
LG
1758 )\r
1759{\r
1760 SVfrVarStorageNode *pNode = NULL;\r
e8a47801 1761 EFI_VARSTORE_ID TmpVarStoreId;\r
30fdf114
LG
1762\r
1763 if (StoreName == NULL) {\r
1764 return VFR_RETURN_FATAL_ERROR;\r
1765 }\r
1766\r
e8a47801 1767 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {\r
da92f276 1768 return VFR_RETURN_REDEFINED;\r
30fdf114 1769 }\r
e8a47801
LG
1770 \r
1771 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1772 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
1773 } else {\r
1774 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1775 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1776 }\r
1777 MarkVarStoreIdUsed (VarStoreId);\r
1778 }\r
30fdf114 1779\r
30fdf114
LG
1780 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
1781 return VFR_RETURN_UNDEFINED;\r
1782 }\r
1783\r
1784 mNewVarStorageNode = pNode;\r
1785\r
1786 return VFR_RETURN_SUCCESS;\r
1787}\r
1788\r
1789EFI_VFR_RETURN_CODE\r
1790CVfrDataStorage::NameTableAddItem (\r
1791 IN EFI_STRING_ID Item\r
1792 )\r
1793{\r
1794 EFI_VARSTORE_ID *NewTable, *OldTable;\r
1795 UINT32 TableSize;\r
1796\r
1797 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
1798 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
1799\r
1800 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
1801 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
1802 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1803 }\r
1804 memcpy (NewTable, OldTable, TableSize);\r
1805 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
1806 }\r
1807\r
1808 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
1809 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
1810\r
1811 return VFR_RETURN_SUCCESS;\r
1812}\r
1813\r
1814EFI_VFR_RETURN_CODE\r
1815CVfrDataStorage::DeclareNameVarStoreEnd (\r
1816 IN EFI_GUID *Guid\r
1817 )\r
1818{\r
1819 mNewVarStorageNode->mGuid = *Guid;\r
1820 mNewVarStorageNode->mNext = mNameVarStoreList;\r
1821 mNameVarStoreList = mNewVarStorageNode;\r
1822\r
1823 mNewVarStorageNode = NULL;\r
1824\r
1825 return VFR_RETURN_SUCCESS;\r
1826}\r
1827\r
1828EFI_VFR_RETURN_CODE \r
1829CVfrDataStorage::DeclareEfiVarStore (\r
1830 IN CHAR8 *StoreName, \r
1831 IN EFI_GUID *Guid, \r
1832 IN EFI_STRING_ID NameStrId,\r
1833 IN UINT32 VarSize,\r
1834 IN BOOLEAN Flag\r
1835 )\r
1836{\r
1837 SVfrVarStorageNode *pNode;\r
1838 EFI_VARSTORE_ID VarStoreId;\r
1839\r
1840 if ((StoreName == NULL) || (Guid == NULL)) {\r
1841 return VFR_RETURN_FATAL_ERROR;\r
1842 }\r
1843\r
1844 if (VarSize > sizeof (UINT64)) {\r
1845 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
1846 }\r
1847\r
4afd3d04 1848 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
da92f276 1849 return VFR_RETURN_REDEFINED;\r
30fdf114
LG
1850 }\r
1851\r
1852 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
1853 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {\r
1854 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1855 }\r
1856\r
1857 pNode->mNext = mEfiVarStoreList;\r
1858 mEfiVarStoreList = pNode;\r
1859\r
1860 return VFR_RETURN_SUCCESS;\r
1861}\r
1862\r
1863EFI_VFR_RETURN_CODE \r
1864CVfrDataStorage::DeclareBufferVarStore (\r
1865 IN CHAR8 *StoreName, \r
1866 IN EFI_GUID *Guid, \r
1867 IN CVfrVarDataTypeDB *DataTypeDB,\r
1868 IN CHAR8 *TypeName,\r
1869 IN EFI_VARSTORE_ID VarStoreId,\r
42c808d4 1870 IN BOOLEAN IsBitVarStore,\r
30fdf114
LG
1871 IN BOOLEAN Flag\r
1872 )\r
1873{\r
1874 SVfrVarStorageNode *pNew = NULL;\r
1875 SVfrDataType *pDataType = NULL;\r
da92f276 1876 EFI_VARSTORE_ID TempVarStoreId;\r
30fdf114
LG
1877\r
1878 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1879 return VFR_RETURN_FATAL_ERROR;\r
1880 }\r
1881\r
4afd3d04 1882 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
da92f276
LG
1883 return VFR_RETURN_REDEFINED;\r
1884 }\r
1885\r
30fdf114
LG
1886 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
1887\r
1888 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1889 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);\r
1890 } else {\r
1891 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1892 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1893 }\r
1894 MarkVarStoreIdUsed (VarStoreId);\r
1895 }\r
1896\r
42c808d4 1897 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {\r
30fdf114
LG
1898 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1899 }\r
1900\r
1901 pNew->mNext = mBufferVarStoreList;\r
1902 mBufferVarStoreList = pNew;\r
1903\r
4afd3d04 1904 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {\r
30fdf114
LG
1905 return VFR_RETURN_FATAL_ERROR;\r
1906 }\r
1907\r
1908 return VFR_RETURN_SUCCESS;\r
1909}\r
1910\r
da92f276
LG
1911EFI_VFR_RETURN_CODE \r
1912CVfrDataStorage::GetVarStoreByDataType (\r
1913 IN CHAR8 *DataTypeName,\r
4afd3d04
LG
1914 OUT SVfrVarStorageNode **VarNode,\r
1915 IN EFI_GUID *VarGuid\r
da92f276
LG
1916 )\r
1917{\r
1918 SVfrVarStorageNode *pNode;\r
1919 SVfrVarStorageNode *MatchNode;\r
1920 \r
1921 //\r
1922 // Framework VFR uses Data type name as varstore name, so don't need check again.\r
1923 //\r
1924 if (VfrCompatibleMode) {\r
1925 return VFR_RETURN_UNDEFINED;\r
1926 }\r
1927\r
1928 MatchNode = NULL;\r
1929 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04
LG
1930 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {\r
1931 continue;\r
1932 }\r
1933\r
1934 if ((VarGuid != NULL)) {\r
1935 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
1936 *VarNode = pNode;\r
1937 return VFR_RETURN_SUCCESS;\r
1938 }\r
1939 } else {\r
da92f276
LG
1940 if (MatchNode == NULL) {\r
1941 MatchNode = pNode;\r
1942 } else {\r
1943 //\r
1944 // More than one varstores referred the same data structures.\r
1945 //\r
1946 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;\r
1947 }\r
1948 }\r
1949 }\r
1950 \r
1951 if (MatchNode == NULL) {\r
1952 return VFR_RETURN_UNDEFINED;\r
1953 }\r
1954\r
1955 *VarNode = MatchNode;\r
1956 return VFR_RETURN_SUCCESS;\r
1957}\r
1958\r
4afd3d04
LG
1959EFI_VARSTORE_ID \r
1960CVfrDataStorage::CheckGuidField (\r
1961 IN SVfrVarStorageNode *pNode,\r
1962 IN EFI_GUID *StoreGuid,\r
1963 IN BOOLEAN *HasFoundOne,\r
1964 OUT EFI_VFR_RETURN_CODE *ReturnCode\r
1965 )\r
1966{\r
1967 if (StoreGuid != NULL) {\r
1968 //\r
1969 // If has guid info, compare the guid filed.\r
1970 //\r
1971 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
1972 //\r
1973 // Both name and guid are same, this this varstore.\r
1974 //\r
1975 mCurrVarStorageNode = pNode;\r
1976 *ReturnCode = VFR_RETURN_SUCCESS;\r
1977 return TRUE;\r
1978 }\r
1979 } else {\r
1980 //\r
1981 // Not has Guid field, check whether this name is the only one.\r
1982 //\r
1983 if (*HasFoundOne) {\r
1984 //\r
1985 // The name has conflict, return name redefined.\r
1986 //\r
1987 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;\r
1988 return TRUE;\r
1989 }\r
1990\r
1991 *HasFoundOne = TRUE;\r
1992 mCurrVarStorageNode = pNode;\r
1993 }\r
1994\r
1995 return FALSE;\r
1996}\r
1997\r
1998/**\r
1999 Base on the input store name and guid to find the varstore id. \r
2000\r
2001 If both name and guid are inputed, base on the name and guid to\r
2002 found the varstore. If only name inputed, base on the name to\r
2003 found the varstore and go on to check whether more than one varstore\r
2004 has the same name. If only has found one varstore, return this\r
2005 varstore; if more than one varstore has same name, return varstore\r
2006 name redefined error. If no varstore found by varstore name, call\r
2007 function GetVarStoreByDataType and use inputed varstore name as \r
2008 data type name to search.\r
2009**/\r
30fdf114
LG
2010EFI_VFR_RETURN_CODE \r
2011CVfrDataStorage::GetVarStoreId (\r
2012 IN CHAR8 *StoreName,\r
4afd3d04
LG
2013 OUT EFI_VARSTORE_ID *VarStoreId,\r
2014 IN EFI_GUID *StoreGuid\r
30fdf114
LG
2015 )\r
2016{\r
da92f276 2017 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114 2018 SVfrVarStorageNode *pNode;\r
4afd3d04
LG
2019 BOOLEAN HasFoundOne = FALSE;\r
2020\r
2021 mCurrVarStorageNode = NULL;\r
30fdf114
LG
2022\r
2023 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2024 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
2025 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
2026 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
2027 return ReturnCode;\r
2028 }\r
30fdf114
LG
2029 }\r
2030 }\r
2031\r
2032 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2033 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
2034 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
2035 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
2036 return ReturnCode;\r
2037 }\r
30fdf114
LG
2038 }\r
2039 }\r
2040\r
2041 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2042 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
2043 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
2044 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
2045 return ReturnCode;\r
2046 }\r
30fdf114
LG
2047 }\r
2048 }\r
2049\r
4afd3d04
LG
2050 if (HasFoundOne) {\r
2051 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
2052 return VFR_RETURN_SUCCESS;\r
2053 }\r
2054\r
da92f276
LG
2055 *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
2056\r
2057 //\r
2058 // Assume that Data strucutre name is used as StoreName, and check again. \r
2059 //\r
4afd3d04 2060 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
da92f276
LG
2061 if (pNode != NULL) {\r
2062 mCurrVarStorageNode = pNode;\r
2063 *VarStoreId = pNode->mVarStoreId;\r
2064 }\r
2065 \r
2066 return ReturnCode;\r
30fdf114
LG
2067}\r
2068\r
2069EFI_VFR_RETURN_CODE\r
2070CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
4afd3d04 2071 IN EFI_VARSTORE_ID VarStoreId,\r
30fdf114
LG
2072 OUT CHAR8 **DataTypeName\r
2073 )\r
2074{\r
2075 SVfrVarStorageNode *pNode;\r
2076\r
4afd3d04 2077 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
30fdf114
LG
2078 return VFR_RETURN_FATAL_ERROR;\r
2079 }\r
2080\r
2081 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04
LG
2082 if (pNode->mVarStoreId == VarStoreId) {\r
2083 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
2084 return VFR_RETURN_SUCCESS;\r
30fdf114
LG
2085 }\r
2086 }\r
2087\r
4afd3d04 2088 return VFR_RETURN_UNDEFINED;\r
30fdf114
LG
2089}\r
2090\r
4afd3d04 2091EFI_VFR_VARSTORE_TYPE\r
30fdf114 2092CVfrDataStorage::GetVarStoreType (\r
4afd3d04 2093 IN EFI_VARSTORE_ID VarStoreId\r
30fdf114
LG
2094 )\r
2095{\r
2096 SVfrVarStorageNode *pNode;\r
4afd3d04 2097 EFI_VFR_VARSTORE_TYPE VarStoreType;\r
30fdf114 2098\r
4afd3d04
LG
2099 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
2100\r
2101 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
2102 return VarStoreType;\r
30fdf114
LG
2103 }\r
2104\r
2105 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 2106 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 2107 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 2108 return VarStoreType;\r
30fdf114
LG
2109 }\r
2110 }\r
2111\r
2112 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 2113 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 2114 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 2115 return VarStoreType;\r
30fdf114
LG
2116 }\r
2117 }\r
2118\r
2119 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 2120 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 2121 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 2122 return VarStoreType;\r
30fdf114
LG
2123 }\r
2124 }\r
2125\r
4afd3d04 2126 return VarStoreType;\r
30fdf114
LG
2127}\r
2128\r
4afd3d04
LG
2129EFI_GUID *\r
2130CVfrDataStorage::GetVarStoreGuid (\r
30fdf114
LG
2131 IN EFI_VARSTORE_ID VarStoreId\r
2132 )\r
2133{\r
2134 SVfrVarStorageNode *pNode;\r
4afd3d04 2135 EFI_GUID *VarGuid;\r
30fdf114 2136\r
4afd3d04 2137 VarGuid = NULL;\r
30fdf114
LG
2138\r
2139 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
4afd3d04 2140 return VarGuid;\r
30fdf114
LG
2141 }\r
2142\r
2143 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2144 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
2145 VarGuid = &pNode->mGuid;\r
2146 return VarGuid;\r
30fdf114
LG
2147 }\r
2148 }\r
2149\r
2150 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2151 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
2152 VarGuid = &pNode->mGuid;\r
2153 return VarGuid;\r
30fdf114
LG
2154 }\r
2155 }\r
2156\r
2157 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2158 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
2159 VarGuid = &pNode->mGuid;\r
2160 return VarGuid;\r
30fdf114
LG
2161 }\r
2162 }\r
2163\r
4afd3d04 2164 return VarGuid;\r
30fdf114
LG
2165}\r
2166\r
2167EFI_VFR_RETURN_CODE\r
2168CVfrDataStorage::GetVarStoreName (\r
2169 IN EFI_VARSTORE_ID VarStoreId, \r
2170 OUT CHAR8 **VarStoreName\r
2171 )\r
2172{\r
2173 SVfrVarStorageNode *pNode;\r
2174\r
2175 if (VarStoreName == NULL) {\r
2176 return VFR_RETURN_FATAL_ERROR;\r
2177 }\r
2178\r
2179 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2180 if (pNode->mVarStoreId == VarStoreId) {\r
2181 *VarStoreName = pNode->mVarStoreName;\r
2182 return VFR_RETURN_SUCCESS;\r
2183 }\r
2184 }\r
2185\r
2186 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2187 if (pNode->mVarStoreId == VarStoreId) {\r
2188 *VarStoreName = pNode->mVarStoreName;\r
2189 return VFR_RETURN_SUCCESS;\r
2190 }\r
2191 }\r
2192\r
2193 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2194 if (pNode->mVarStoreId == VarStoreId) {\r
2195 *VarStoreName = pNode->mVarStoreName;\r
2196 return VFR_RETURN_SUCCESS;\r
2197 }\r
2198 }\r
2199\r
2200 *VarStoreName = NULL;\r
2201 return VFR_RETURN_UNDEFINED;\r
2202}\r
2203\r
2204EFI_VFR_RETURN_CODE\r
2205CVfrDataStorage::GetEfiVarStoreInfo (\r
2206 IN OUT EFI_VARSTORE_INFO *Info\r
2207 )\r
2208{\r
2209 if (Info == NULL) {\r
2210 return VFR_RETURN_FATAL_ERROR;\r
2211 }\r
2212\r
2213 if (mCurrVarStorageNode == NULL) {\r
2214 return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
2215 }\r
2216\r
2217 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
2218 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
2219 switch (Info->mVarTotalSize) {\r
2220 case 1:\r
2221 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
2222 break;\r
2223 case 2:\r
2224 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
2225 break;\r
2226 case 4:\r
2227 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
2228 break;\r
2229 case 8:\r
2230 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
2231 break;\r
2232 default :\r
2233 return VFR_RETURN_FATAL_ERROR;\r
2234 }\r
2235\r
2236 return VFR_RETURN_SUCCESS;\r
2237}\r
2238\r
74bbe31b
DB
2239EFI_VFR_RETURN_CODE\r
2240CVfrDataStorage::AddBufferVarStoreFieldInfo (\r
2241 IN EFI_VARSTORE_INFO *Info\r
2242 )\r
2243{\r
2244 BufferVarStoreFieldInfoNode *pNew;\r
2245\r
2246 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {\r
2247 return VFR_RETURN_FATAL_ERROR;\r
2248 }\r
2249\r
2250 if (mBufferFieldInfoListHead == NULL) {\r
2251 mBufferFieldInfoListHead = pNew;\r
2252 mBufferFieldInfoListTail= pNew;\r
2253 } else {\r
2254 mBufferFieldInfoListTail->mNext = pNew;\r
2255 mBufferFieldInfoListTail = pNew;\r
2256 }\r
2257\r
2258 return VFR_RETURN_SUCCESS;\r
2259}\r
2260\r
2261EFI_VFR_RETURN_CODE\r
2262CVfrDataStorage::GetBufferVarStoreFieldInfo (\r
2263 IN OUT EFI_VARSTORE_INFO *Info\r
2264 )\r
2265{\r
2266 BufferVarStoreFieldInfoNode *pNode;\r
2267\r
2268 pNode = mBufferFieldInfoListHead;\r
2269 while (pNode != NULL) {\r
2270 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&\r
2271 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {\r
2272 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;\r
2273 Info->mVarType = pNode->mVarStoreInfo.mVarType;\r
2274 return VFR_RETURN_SUCCESS;\r
2275 }\r
2276 pNode = pNode->mNext;\r
2277 }\r
2278 return VFR_RETURN_FATAL_ERROR;\r
2279}\r
2280\r
30fdf114
LG
2281EFI_VFR_RETURN_CODE\r
2282CVfrDataStorage::GetNameVarStoreInfo (\r
2283 OUT EFI_VARSTORE_INFO *Info,\r
2284 IN UINT32 Index\r
2285 )\r
2286{\r
2287 if (Info == NULL) {\r
2288 return VFR_RETURN_FATAL_ERROR;\r
2289 }\r
2290\r
2291 if (mCurrVarStorageNode == NULL) {\r
2292 return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
2293 }\r
2294 \r
2295 //\r
2296 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
2297 //\r
2298 if (VfrCompatibleMode) {\r
2299 if (Index == 0) {\r
2300 return VFR_RETURN_ERROR_ARRARY_NUM;\r
2301 }\r
2302 Index --;\r
2303 }\r
2304\r
2305 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
2306\r
2307 return VFR_RETURN_SUCCESS;\r
2308}\r
2309\r
30fdf114
LG
2310SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
2311 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
2312 IN CHAR8 *RefName, \r
2313 IN EFI_STRING_ID DefaultStoreNameId, \r
2314 IN UINT16 DefaultId\r
2315 )\r
2316{\r
2317 mObjBinAddr = ObjBinAddr;\r
2318\r
2319 if (RefName != NULL) {\r
2320 mRefName = new CHAR8[strlen (RefName) + 1];\r
2321 strcpy (mRefName, RefName);\r
2322 } else {\r
2323 mRefName = NULL;\r
2324 }\r
2325\r
2326 mNext = NULL;\r
2327 mDefaultId = DefaultId;\r
2328 mDefaultStoreNameId = DefaultStoreNameId;\r
2329}\r
2330\r
2331SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
2332 VOID\r
2333 )\r
2334{\r
2335 if (mRefName != NULL) {\r
fd542523 2336 delete[] mRefName;\r
30fdf114
LG
2337 }\r
2338}\r
2339\r
2340CVfrDefaultStore::CVfrDefaultStore (\r
2341 VOID\r
2342 )\r
2343{\r
2344 mDefaultStoreList = NULL;\r
2345}\r
2346\r
2347CVfrDefaultStore::~CVfrDefaultStore (\r
2348 VOID\r
2349 )\r
2350{\r
2351 SVfrDefaultStoreNode *pTmp = NULL;\r
2352\r
2353 while (mDefaultStoreList != NULL) {\r
2354 pTmp = mDefaultStoreList;\r
2355 mDefaultStoreList = mDefaultStoreList->mNext;\r
2356 delete pTmp;\r
2357 }\r
2358}\r
2359\r
2360EFI_VFR_RETURN_CODE\r
2361CVfrDefaultStore::RegisterDefaultStore (\r
2362 IN CHAR8 *ObjBinAddr,\r
2363 IN CHAR8 *RefName,\r
2364 IN EFI_STRING_ID DefaultStoreNameId,\r
2365 IN UINT16 DefaultId\r
2366 )\r
2367{\r
2368 SVfrDefaultStoreNode *pNode = NULL;\r
2369\r
2370 if (RefName == NULL) {\r
2371 return VFR_RETURN_FATAL_ERROR;\r
2372 }\r
2373\r
2374 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2375 if (strcmp (pNode->mRefName, RefName) == 0) {\r
2376 return VFR_RETURN_REDEFINED;\r
2377 }\r
2378 }\r
2379\r
2380 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
2381 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2382 }\r
2383\r
2384 pNode->mNext = mDefaultStoreList;\r
2385 mDefaultStoreList = pNode;\r
2386\r
2387 return VFR_RETURN_SUCCESS;\r
2388}\r
2389\r
2390/*\r
2391 * assign new reference name or new default store name id only if \r
2392 * the original is invalid\r
2393 */\r
2394EFI_VFR_RETURN_CODE\r
2395CVfrDefaultStore::ReRegisterDefaultStoreById (\r
2396 IN UINT16 DefaultId,\r
2397 IN CHAR8 *RefName,\r
2398 IN EFI_STRING_ID DefaultStoreNameId\r
2399 )\r
2400{\r
2401 SVfrDefaultStoreNode *pNode = NULL;\r
2402\r
2403 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2404 if (pNode->mDefaultId == DefaultId) {\r
2405 break;\r
2406 }\r
2407 }\r
2408\r
2409 if (pNode == NULL) {\r
2410 return VFR_RETURN_UNDEFINED;\r
2411 } else {\r
2412 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
2413 pNode->mDefaultStoreNameId = DefaultStoreNameId;\r
2414 if (pNode->mObjBinAddr != NULL) {\r
2415 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
2416 }\r
2417 } else {\r
2418 return VFR_RETURN_REDEFINED;\r
2419 }\r
2420\r
2421 if (RefName != NULL) {\r
2422 delete pNode->mRefName;\r
2423 pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
2424 if (pNode->mRefName != NULL) {\r
2425 strcpy (pNode->mRefName, RefName);\r
2426 }\r
2427 }\r
2428 }\r
2429\r
2430 return VFR_RETURN_SUCCESS;\r
2431}\r
2432\r
2433BOOLEAN\r
2434CVfrDefaultStore::DefaultIdRegistered (\r
2435 IN UINT16 DefaultId\r
2436 )\r
2437{\r
2438 SVfrDefaultStoreNode *pNode = NULL;\r
2439\r
2440 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2441 if (pNode->mDefaultId == DefaultId) {\r
2442 return TRUE;\r
2443 }\r
2444 }\r
2445\r
2446 return FALSE;\r
2447}\r
2448\r
2449EFI_VFR_RETURN_CODE\r
2450CVfrDefaultStore::GetDefaultId (\r
2451 IN CHAR8 *RefName,\r
2452 OUT UINT16 *DefaultId\r
2453 )\r
2454{\r
2455 SVfrDefaultStoreNode *pTmp = NULL;\r
2456\r
2457 if (DefaultId == NULL) {\r
2458 return VFR_RETURN_FATAL_ERROR;\r
2459 }\r
2460\r
2461 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
2462 if (strcmp (pTmp->mRefName, RefName) == 0) {\r
2463 *DefaultId = pTmp->mDefaultId;\r
2464 return VFR_RETURN_SUCCESS;\r
2465 }\r
2466 }\r
2467\r
2468 return VFR_RETURN_UNDEFINED;\r
2469}\r
2470\r
30fdf114
LG
2471EFI_VFR_RETURN_CODE\r
2472CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2473 IN EFI_VARSTORE_ID DefaultId,\r
2474 IN EFI_VARSTORE_INFO &Info,\r
2475 IN CHAR8 *VarStoreName,\r
4afd3d04 2476 IN EFI_GUID *VarStoreGuid,\r
30fdf114
LG
2477 IN UINT8 Type,\r
2478 IN EFI_IFR_TYPE_VALUE Value\r
2479 )\r
2480{\r
2481 SVfrDefaultStoreNode *pNode = NULL;\r
2482 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2483 INTN Returnvalue = 0;\r
2484\r
2485 if (VarStoreName == NULL) {\r
2486 return VFR_RETURN_FATAL_ERROR;\r
2487 }\r
2488\r
2489 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2490 if (pNode->mDefaultId == DefaultId) {\r
2491 break;\r
2492 }\r
2493 }\r
2494\r
2495 if (pNode == NULL) {\r
2496 return VFR_RETURN_UNDEFINED;\r
2497 }\r
2498\r
2499 gCVfrBufferConfig.Open ();\r
2500\r
2501 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
4afd3d04
LG
2502 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {\r
2503 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
30fdf114
LG
2504 goto WriteError;\r
2505 }\r
2506 }\r
2507 \r
2508 gCVfrBufferConfig.Close ();\r
2509\r
2510 return VFR_RETURN_SUCCESS;\r
2511\r
2512WriteError:\r
2513 gCVfrBufferConfig.Close ();\r
2514 return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2515}\r
2516\r
2517SVfrRuleNode::SVfrRuleNode (\r
2518 IN CHAR8 *RuleName,\r
2519 IN UINT8 RuleId\r
2520 )\r
2521{\r
2522 if (RuleName != NULL) {\r
2523 mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2524 strcpy (mRuleName, RuleName);\r
2525 } else {\r
2526 mRuleName = NULL;\r
2527 }\r
2528\r
2529 mNext = NULL;\r
2530 mRuleId = RuleId;\r
2531}\r
2532\r
2533SVfrRuleNode::~SVfrRuleNode (\r
2534 VOID\r
2535 )\r
2536{\r
2537 if (mRuleName != NULL) {\r
fd542523 2538 delete[] mRuleName;\r
30fdf114
LG
2539 }\r
2540}\r
2541\r
2542CVfrRulesDB::CVfrRulesDB ()\r
2543{\r
2544 mRuleList = NULL;\r
2545 mFreeRuleId = EFI_VARSTORE_ID_START;\r
2546}\r
2547\r
2548CVfrRulesDB::~CVfrRulesDB ()\r
2549{\r
2550 SVfrRuleNode *pNode;\r
2551\r
2552 while(mRuleList != NULL) {\r
2553 pNode = mRuleList;\r
2554 mRuleList = mRuleList->mNext;\r
2555 delete pNode;\r
2556 }\r
2557}\r
2558\r
2559VOID\r
2560CVfrRulesDB::RegisterRule (\r
2561 IN CHAR8 *RuleName\r
2562 )\r
2563{\r
2564 SVfrRuleNode *pNew;\r
2565\r
2566 if (RuleName == NULL) {\r
2567 return ;\r
2568 }\r
2569\r
2570 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2571 return ;\r
2572 }\r
2573\r
2574 mFreeRuleId++;\r
2575\r
2576 pNew->mNext = mRuleList;\r
2577 mRuleList = pNew;\r
2578}\r
2579\r
2580UINT8\r
2581CVfrRulesDB::GetRuleId (\r
2582 IN CHAR8 *RuleName\r
2583 )\r
2584{\r
2585 SVfrRuleNode *pNode;\r
2586\r
2587 if (RuleName == NULL) {\r
2588 return EFI_RULE_ID_INVALID;\r
2589 }\r
2590\r
2591 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2592 if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2593 return pNode->mRuleId;\r
2594 }\r
2595 }\r
2596\r
2597 return EFI_RULE_ID_INVALID;\r
2598}\r
2599\r
2600CVfrRulesDB gCVfrRulesDB;\r
2601\r
2602EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2603 VOID\r
2604 )\r
2605{\r
2606 mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2607 mInfo.mVarName = EFI_STRING_ID_INVALID;\r
2608 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2609 mVarType = EFI_IFR_TYPE_OTHER;\r
2610 mVarTotalSize = 0;\r
42c808d4 2611 mIsBitVar = FALSE;\r
30fdf114
LG
2612}\r
2613\r
2614EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2615 IN EFI_VARSTORE_INFO &Info\r
2616 )\r
2617{\r
2618 mVarStoreId = Info.mVarStoreId;\r
2619 mInfo.mVarName = Info.mInfo.mVarName;\r
2620 mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2621 mVarType = Info.mVarType;\r
2622 mVarTotalSize = Info.mVarTotalSize;\r
42c808d4 2623 mIsBitVar = Info.mIsBitVar;\r
30fdf114
LG
2624}\r
2625\r
0d46defe
HW
2626EFI_VARSTORE_INFO&\r
2627EFI_VARSTORE_INFO::operator= (\r
2628 IN CONST EFI_VARSTORE_INFO &Info\r
2629 )\r
2630{\r
2631 if (this != &Info) {\r
2632 mVarStoreId = Info.mVarStoreId;\r
2633 mInfo.mVarName = Info.mInfo.mVarName;\r
2634 mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2635 mVarType = Info.mVarType;\r
2636 mVarTotalSize = Info.mVarTotalSize;\r
42c808d4 2637 mIsBitVar = Info.mIsBitVar;\r
0d46defe
HW
2638 }\r
2639\r
2640 return *this;\r
2641}\r
2642\r
30fdf114
LG
2643BOOLEAN\r
2644EFI_VARSTORE_INFO::operator == (\r
2645 IN EFI_VARSTORE_INFO *Info\r
2646 )\r
2647{\r
2648 if ((mVarStoreId == Info->mVarStoreId) &&\r
2649 (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2650 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2651 (mVarType == Info->mVarType) &&\r
42c808d4
DB
2652 (mVarTotalSize == Info->mVarTotalSize) &&\r
2653 (mIsBitVar == Info->mIsBitVar)) {\r
30fdf114
LG
2654 return TRUE;\r
2655 }\r
2656\r
2657 return FALSE;\r
2658}\r
2659\r
74bbe31b
DB
2660BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(\r
2661 IN EFI_VARSTORE_INFO *Info\r
2662 )\r
2663{\r
2664 mVarStoreInfo.mVarType = Info->mVarType;\r
2665 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;\r
2666 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;\r
2667 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;\r
2668 mNext = NULL;\r
2669}\r
2670\r
2671BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()\r
2672{\r
2673 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;\r
2674 mVarStoreInfo.mVarTotalSize = 0;\r
2675 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2676 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2677 mNext = NULL;\r
2678}\r
2679\r
30fdf114
LG
2680static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2681\r
2682EFI_QUESTION_ID\r
2683CVfrQuestionDB::GetFreeQuestionId (\r
2684 VOID\r
2685 )\r
2686{\r
2687 UINT32 Index, Mask, Offset;\r
2688\r
2689 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2690 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2691 break;\r
2692 }\r
2693 }\r
2694\r
bab5ad2f
HW
2695 if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {\r
2696 return EFI_QUESTION_ID_INVALID;\r
2697 }\r
2698\r
30fdf114
LG
2699 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2700 if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2701 mFreeQIdBitMap[Index] |= Mask;\r
2702 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2703 }\r
2704 }\r
2705\r
2706 return EFI_QUESTION_ID_INVALID;\r
2707}\r
2708\r
2709BOOLEAN\r
2710CVfrQuestionDB::ChekQuestionIdFree (\r
2711 IN EFI_QUESTION_ID QId\r
2712 )\r
2713{\r
2714 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2715 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2716\r
2717 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2718}\r
2719\r
2720VOID\r
2721CVfrQuestionDB::MarkQuestionIdUsed (\r
2722 IN EFI_QUESTION_ID QId\r
2723 )\r
2724{\r
2725 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2726 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2727\r
2728 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2729}\r
2730\r
2731VOID\r
2732CVfrQuestionDB::MarkQuestionIdUnused (\r
2733 IN EFI_QUESTION_ID QId\r
2734 )\r
2735{\r
2736 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2737 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2738\r
2739 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2740}\r
2741\r
2742SVfrQuestionNode::SVfrQuestionNode (\r
2743 IN CHAR8 *Name,\r
2744 IN CHAR8 *VarIdStr,\r
2745 IN UINT32 BitMask\r
2746 )\r
2747{\r
2748 mName = NULL;\r
2749 mVarIdStr = NULL;\r
2750 mQuestionId = EFI_QUESTION_ID_INVALID;\r
2751 mBitMask = BitMask;\r
2752 mNext = NULL;\r
52302d4d 2753 mQtype = QUESTION_NORMAL;\r
30fdf114
LG
2754\r
2755 if (Name == NULL) {\r
2756 mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2757 strcpy (mName, "$DEFAULT");\r
2758 } else {\r
2759 mName = new CHAR8[strlen (Name) + 1];\r
2760 strcpy (mName, Name);\r
2761 }\r
2762\r
2763 if (VarIdStr != NULL) {\r
2764 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2765 strcpy (mVarIdStr, VarIdStr);\r
2766 } else {\r
2767 mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2768 strcpy (mVarIdStr, "$");\r
2769 }\r
2770}\r
2771\r
2772SVfrQuestionNode::~SVfrQuestionNode (\r
2773 VOID\r
2774 )\r
2775{\r
2776 if (mName != NULL) {\r
fd542523 2777 delete[] mName;\r
30fdf114
LG
2778 }\r
2779\r
2780 if (mVarIdStr != NULL) {\r
fd542523 2781 delete[] mVarIdStr;\r
30fdf114
LG
2782 }\r
2783}\r
2784\r
2785CVfrQuestionDB::CVfrQuestionDB ()\r
2786{\r
2787 UINT32 Index;\r
2788\r
2789 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2790 mFreeQIdBitMap[Index] = 0;\r
2791 }\r
2792\r
2793 // Question ID 0 is reserved.\r
2794 mFreeQIdBitMap[0] = 0x80000000;\r
2795 mQuestionList = NULL;\r
2796}\r
2797\r
2798CVfrQuestionDB::~CVfrQuestionDB ()\r
2799{\r
2800 SVfrQuestionNode *pNode;\r
2801\r
2802 while (mQuestionList != NULL) {\r
2803 pNode = mQuestionList;\r
2804 mQuestionList = mQuestionList->mNext;\r
2805 delete pNode;\r
2806 }\r
2807}\r
2808\r
2809//\r
2810// Reset to init state\r
2811//\r
2812VOID\r
2813CVfrQuestionDB::ResetInit(\r
2814 IN VOID\r
2815 )\r
2816{\r
2817 UINT32 Index;\r
2818 SVfrQuestionNode *pNode;\r
2819\r
2820 while (mQuestionList != NULL) {\r
2821 pNode = mQuestionList;\r
2822 mQuestionList = mQuestionList->mNext;\r
2823 delete pNode;\r
2824 }\r
2825\r
2826 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2827 mFreeQIdBitMap[Index] = 0;\r
2828 }\r
2829\r
2830 // Question ID 0 is reserved.\r
2831 mFreeQIdBitMap[0] = 0x80000000;\r
2832 mQuestionList = NULL; \r
2833}\r
2834\r
2835VOID\r
2836CVfrQuestionDB::PrintAllQuestion (\r
2837 VOID\r
2838 )\r
2839{\r
2840 SVfrQuestionNode *pNode = NULL;\r
2841\r
2842 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2843 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2844 }\r
2845}\r
2846\r
2847EFI_VFR_RETURN_CODE\r
2848CVfrQuestionDB::RegisterQuestion (\r
2849 IN CHAR8 *Name,\r
2850 IN CHAR8 *VarIdStr,\r
2851 IN OUT EFI_QUESTION_ID &QuestionId\r
2852 )\r
2853{\r
2854 SVfrQuestionNode *pNode = NULL;\r
2855\r
2856 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2857 return VFR_RETURN_REDEFINED;\r
2858 }\r
2859\r
2860 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2861 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2862 }\r
2863\r
2864 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2865 QuestionId = GetFreeQuestionId ();\r
2866 } else {\r
2867 //\r
2868 // For Framework Vfr, don't check question ID conflict.\r
2869 //\r
2870 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2871 delete pNode;\r
2872 return VFR_RETURN_QUESTIONID_REDEFINED;\r
2873 }\r
2874 MarkQuestionIdUsed (QuestionId);\r
2875 }\r
2876 pNode->mQuestionId = QuestionId;\r
2877\r
2878 pNode->mNext = mQuestionList;\r
2879 mQuestionList = pNode;\r
2880\r
2881 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2882\r
2883 return VFR_RETURN_SUCCESS;\r
2884}\r
2885\r
2886VOID\r
2887CVfrQuestionDB::RegisterOldDateQuestion (\r
2888 IN CHAR8 *YearVarId,\r
2889 IN CHAR8 *MonthVarId,\r
2890 IN CHAR8 *DayVarId,\r
2891 IN OUT EFI_QUESTION_ID &QuestionId\r
2892 )\r
2893{\r
2894 SVfrQuestionNode *pNode[3] = {NULL, };\r
2895 UINT32 Index;\r
2896\r
2897 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2898 return;\r
2899 }\r
2900\r
2901 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2902 goto Err;\r
2903 }\r
2904 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2905 goto Err;\r
2906 }\r
2907 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2908 goto Err;\r
2909 }\r
2910\r
2911 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2912 QuestionId = GetFreeQuestionId ();\r
2913 } else {\r
2914 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2915 goto Err;\r
2916 }\r
2917 MarkQuestionIdUsed (QuestionId);\r
2918 }\r
2919\r
2920 pNode[0]->mQuestionId = QuestionId;\r
2921 pNode[1]->mQuestionId = QuestionId;\r
2922 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
2923 pNode[0]->mQtype = QUESTION_DATE;\r
2924 pNode[1]->mQtype = QUESTION_DATE;\r
2925 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
2926 pNode[0]->mNext = pNode[1];\r
2927 pNode[1]->mNext = pNode[2];\r
2928 pNode[2]->mNext = mQuestionList;\r
2929 mQuestionList = pNode[0];\r
2930\r
2931 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2932 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2933 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2934\r
2935 return;\r
2936\r
2937Err:\r
2938 for (Index = 0; Index < 3; Index++) {\r
2939 if (pNode[Index] != NULL) {\r
2940 delete pNode[Index];\r
2941 }\r
2942 }\r
2943 QuestionId = EFI_QUESTION_ID_INVALID;\r
2944}\r
2945\r
2946VOID\r
2947CVfrQuestionDB::RegisterNewDateQuestion (\r
2948 IN CHAR8 *Name,\r
2949 IN CHAR8 *BaseVarId,\r
2950 IN OUT EFI_QUESTION_ID &QuestionId\r
2951 )\r
2952{\r
2953 SVfrQuestionNode *pNode[3] = {NULL, };\r
2954 UINT32 Len;\r
2955 CHAR8 *VarIdStr[3] = {NULL, };\r
2956 CHAR8 Index;\r
2957\r
4afd3d04 2958 if (BaseVarId == NULL && Name == NULL) {\r
e8a47801
LG
2959 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2960 QuestionId = GetFreeQuestionId ();\r
2961 } else {\r
2962 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2963 goto Err;\r
2964 }\r
2965 MarkQuestionIdUsed (QuestionId);\r
2966 }\r
30fdf114
LG
2967 return;\r
2968 }\r
2969\r
4afd3d04
LG
2970 if (BaseVarId != NULL) {\r
2971 Len = strlen (BaseVarId);\r
30fdf114 2972\r
4afd3d04
LG
2973 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2974 if (VarIdStr[0] != NULL) {\r
2975 strcpy (VarIdStr[0], BaseVarId);\r
2976 strcat (VarIdStr[0], ".Year");\r
2977 }\r
2978 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2979 if (VarIdStr[1] != NULL) {\r
2980 strcpy (VarIdStr[1], BaseVarId);\r
2981 strcat (VarIdStr[1], ".Month");\r
2982 }\r
2983 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2984 if (VarIdStr[2] != NULL) {\r
2985 strcpy (VarIdStr[2], BaseVarId);\r
2986 strcat (VarIdStr[2], ".Day");\r
2987 }\r
2988 } else {\r
2989 Len = strlen (Name);\r
2990\r
2991 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2992 if (VarIdStr[0] != NULL) {\r
2993 strcpy (VarIdStr[0], Name);\r
2994 strcat (VarIdStr[0], ".Year");\r
2995 }\r
2996 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2997 if (VarIdStr[1] != NULL) {\r
2998 strcpy (VarIdStr[1], Name);\r
2999 strcat (VarIdStr[1], ".Month");\r
3000 }\r
3001 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
3002 if (VarIdStr[2] != NULL) {\r
3003 strcpy (VarIdStr[2], Name);\r
3004 strcat (VarIdStr[2], ".Day");\r
3005 }\r
30fdf114
LG
3006 }\r
3007\r
3008 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
3009 goto Err;\r
3010 }\r
3011 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
3012 goto Err;\r
3013 }\r
3014 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
3015 goto Err;\r
3016 }\r
3017\r
3018 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3019 QuestionId = GetFreeQuestionId ();\r
3020 } else {\r
3021 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3022 goto Err;\r
3023 }\r
3024 MarkQuestionIdUsed (QuestionId);\r
3025 }\r
3026\r
3027 pNode[0]->mQuestionId = QuestionId;\r
3028 pNode[1]->mQuestionId = QuestionId;\r
3029 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
3030 pNode[0]->mQtype = QUESTION_DATE;\r
3031 pNode[1]->mQtype = QUESTION_DATE;\r
3032 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
3033 pNode[0]->mNext = pNode[1];\r
3034 pNode[1]->mNext = pNode[2];\r
3035 pNode[2]->mNext = mQuestionList;\r
3036 mQuestionList = pNode[0];\r
3037\r
3038 for (Index = 0; Index < 3; Index++) {\r
3039 if (VarIdStr[Index] != NULL) {\r
3040 delete VarIdStr[Index];\r
3041 }\r
3042 }\r
3043\r
3044 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3045 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3046 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3047\r
3048 return;\r
3049\r
3050Err:\r
3051 for (Index = 0; Index < 3; Index++) {\r
3052 if (pNode[Index] != NULL) {\r
3053 delete pNode[Index];\r
3054 }\r
3055\r
3056 if (VarIdStr[Index] != NULL) {\r
3057 delete VarIdStr[Index];\r
3058 }\r
3059 }\r
3060}\r
3061\r
3062VOID\r
3063CVfrQuestionDB::RegisterOldTimeQuestion (\r
3064 IN CHAR8 *HourVarId,\r
3065 IN CHAR8 *MinuteVarId,\r
3066 IN CHAR8 *SecondVarId,\r
3067 IN OUT EFI_QUESTION_ID &QuestionId\r
3068 )\r
3069{\r
3070 SVfrQuestionNode *pNode[3] = {NULL, };\r
3071 UINT32 Index;\r
3072\r
3073 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
3074 return;\r
3075 }\r
3076\r
3077 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
3078 goto Err;\r
3079 }\r
3080 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
3081 goto Err;\r
3082 }\r
3083 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
3084 goto Err;\r
3085 }\r
3086\r
3087 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3088 QuestionId = GetFreeQuestionId ();\r
3089 } else {\r
3090 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3091 goto Err;\r
3092 }\r
3093 MarkQuestionIdUsed (QuestionId);\r
3094 }\r
3095\r
3096 pNode[0]->mQuestionId = QuestionId;\r
3097 pNode[1]->mQuestionId = QuestionId;\r
3098 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
3099 pNode[0]->mQtype = QUESTION_TIME;\r
3100 pNode[1]->mQtype = QUESTION_TIME;\r
3101 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
3102 pNode[0]->mNext = pNode[1];\r
3103 pNode[1]->mNext = pNode[2];\r
3104 pNode[2]->mNext = mQuestionList;\r
3105 mQuestionList = pNode[0];\r
3106\r
3107 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3108 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3109 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3110\r
3111 return;\r
3112\r
3113Err:\r
3114 for (Index = 0; Index < 3; Index++) {\r
3115 if (pNode[Index] != NULL) {\r
3116 delete pNode[Index];\r
3117 }\r
3118 }\r
3119 QuestionId = EFI_QUESTION_ID_INVALID;\r
3120}\r
3121\r
3122VOID\r
3123CVfrQuestionDB::RegisterNewTimeQuestion (\r
3124 IN CHAR8 *Name,\r
3125 IN CHAR8 *BaseVarId,\r
3126 IN OUT EFI_QUESTION_ID &QuestionId\r
3127 )\r
3128{\r
3129 SVfrQuestionNode *pNode[3] = {NULL, };\r
3130 UINT32 Len;\r
3131 CHAR8 *VarIdStr[3] = {NULL, };\r
3132 CHAR8 Index;\r
3133\r
4afd3d04 3134 if (BaseVarId == NULL && Name == NULL) {\r
e8a47801
LG
3135 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3136 QuestionId = GetFreeQuestionId ();\r
3137 } else {\r
3138 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3139 goto Err;\r
3140 }\r
3141 MarkQuestionIdUsed (QuestionId);\r
3142 }\r
30fdf114
LG
3143 return;\r
3144 }\r
3145\r
4afd3d04
LG
3146 if (BaseVarId != NULL) {\r
3147 Len = strlen (BaseVarId);\r
30fdf114 3148\r
4afd3d04
LG
3149 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
3150 if (VarIdStr[0] != NULL) {\r
3151 strcpy (VarIdStr[0], BaseVarId);\r
3152 strcat (VarIdStr[0], ".Hour");\r
3153 }\r
3154 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
3155 if (VarIdStr[1] != NULL) {\r
3156 strcpy (VarIdStr[1], BaseVarId);\r
3157 strcat (VarIdStr[1], ".Minute");\r
3158 }\r
3159 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
3160 if (VarIdStr[2] != NULL) {\r
3161 strcpy (VarIdStr[2], BaseVarId);\r
3162 strcat (VarIdStr[2], ".Second");\r
3163 }\r
3164 } else {\r
3165 Len = strlen (Name);\r
3166\r
3167 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
3168 if (VarIdStr[0] != NULL) {\r
3169 strcpy (VarIdStr[0], Name);\r
3170 strcat (VarIdStr[0], ".Hour");\r
3171 }\r
3172 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
3173 if (VarIdStr[1] != NULL) {\r
3174 strcpy (VarIdStr[1], Name);\r
3175 strcat (VarIdStr[1], ".Minute");\r
3176 }\r
3177 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
3178 if (VarIdStr[2] != NULL) {\r
3179 strcpy (VarIdStr[2], Name);\r
3180 strcat (VarIdStr[2], ".Second");\r
3181 }\r
30fdf114
LG
3182 }\r
3183\r
3184 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
3185 goto Err;\r
3186 }\r
3187 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
3188 goto Err;\r
3189 }\r
3190 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
3191 goto Err;\r
3192 }\r
3193\r
3194 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3195 QuestionId = GetFreeQuestionId ();\r
3196 } else {\r
3197 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3198 goto Err;\r
3199 }\r
3200 MarkQuestionIdUsed (QuestionId);\r
3201 }\r
3202\r
3203 pNode[0]->mQuestionId = QuestionId;\r
3204 pNode[1]->mQuestionId = QuestionId;\r
3205 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
3206 pNode[0]->mQtype = QUESTION_TIME;\r
3207 pNode[1]->mQtype = QUESTION_TIME;\r
3208 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
3209 pNode[0]->mNext = pNode[1];\r
3210 pNode[1]->mNext = pNode[2];\r
3211 pNode[2]->mNext = mQuestionList;\r
3212 mQuestionList = pNode[0];\r
3213\r
3214 for (Index = 0; Index < 3; Index++) {\r
3215 if (VarIdStr[Index] != NULL) {\r
3216 delete VarIdStr[Index];\r
3217 }\r
3218 }\r
3219\r
3220 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3221 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3222 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3223\r
3224 return;\r
3225\r
3226Err:\r
3227 for (Index = 0; Index < 3; Index++) {\r
3228 if (pNode[Index] != NULL) {\r
3229 delete pNode[Index];\r
3230 }\r
3231\r
3232 if (VarIdStr[Index] != NULL) {\r
3233 delete VarIdStr[Index];\r
3234 }\r
3235 }\r
3236}\r
3237\r
4234283c
LG
3238VOID \r
3239CVfrQuestionDB::RegisterRefQuestion (\r
3240 IN CHAR8 *Name,\r
3241 IN CHAR8 *BaseVarId,\r
3242 IN OUT EFI_QUESTION_ID &QuestionId\r
3243 )\r
3244{\r
3245 SVfrQuestionNode *pNode[4] = {NULL, };\r
3246 UINT32 Len;\r
3247 CHAR8 *VarIdStr[4] = {NULL, };\r
3248 CHAR8 Index;\r
3249\r
4afd3d04 3250 if (BaseVarId == NULL && Name == NULL) {\r
4234283c
LG
3251 return;\r
3252 }\r
3253\r
4afd3d04
LG
3254 if (BaseVarId != NULL) {\r
3255 Len = strlen (BaseVarId);\r
4234283c 3256\r
4afd3d04
LG
3257 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
3258 if (VarIdStr[0] != NULL) {\r
3259 strcpy (VarIdStr[0], BaseVarId);\r
3260 strcat (VarIdStr[0], ".QuestionId");\r
3261 }\r
3262 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
3263 if (VarIdStr[1] != NULL) {\r
3264 strcpy (VarIdStr[1], BaseVarId);\r
3265 strcat (VarIdStr[1], ".FormId");\r
3266 }\r
3267 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
3268 if (VarIdStr[2] != NULL) {\r
3269 strcpy (VarIdStr[2], BaseVarId);\r
3270 strcat (VarIdStr[2], ".FormSetGuid");\r
3271 }\r
3272 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
3273 if (VarIdStr[3] != NULL) {\r
3274 strcpy (VarIdStr[3], BaseVarId);\r
3275 strcat (VarIdStr[3], ".DevicePath");\r
3276 }\r
3277 } else {\r
3278 Len = strlen (Name);\r
3279\r
3280 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
3281 if (VarIdStr[0] != NULL) {\r
3282 strcpy (VarIdStr[0], Name);\r
3283 strcat (VarIdStr[0], ".QuestionId");\r
3284 }\r
3285 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
3286 if (VarIdStr[1] != NULL) {\r
3287 strcpy (VarIdStr[1], Name);\r
3288 strcat (VarIdStr[1], ".FormId");\r
3289 }\r
3290 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
3291 if (VarIdStr[2] != NULL) {\r
3292 strcpy (VarIdStr[2], Name);\r
3293 strcat (VarIdStr[2], ".FormSetGuid");\r
3294 }\r
3295 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
3296 if (VarIdStr[3] != NULL) {\r
3297 strcpy (VarIdStr[3], Name);\r
3298 strcat (VarIdStr[3], ".DevicePath");\r
3299 }\r
4234283c
LG
3300 }\r
3301\r
3302 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {\r
3303 goto Err;\r
3304 }\r
3305 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {\r
3306 goto Err;\r
3307 }\r
3308 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {\r
3309 goto Err;\r
3310 }\r
3311 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {\r
3312 goto Err;\r
3313 }\r
3314\r
3315 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3316 QuestionId = GetFreeQuestionId ();\r
3317 } else {\r
3318 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3319 goto Err;\r
3320 }\r
3321 MarkQuestionIdUsed (QuestionId);\r
3322 }\r
3323\r
3324 pNode[0]->mQuestionId = QuestionId;\r
3325 pNode[1]->mQuestionId = QuestionId;\r
3326 pNode[2]->mQuestionId = QuestionId;\r
3327 pNode[3]->mQuestionId = QuestionId; \r
3328 pNode[0]->mQtype = QUESTION_REF;\r
3329 pNode[1]->mQtype = QUESTION_REF;\r
3330 pNode[2]->mQtype = QUESTION_REF;\r
3331 pNode[3]->mQtype = QUESTION_REF; \r
3332 pNode[0]->mNext = pNode[1];\r
3333 pNode[1]->mNext = pNode[2];\r
3334 pNode[2]->mNext = pNode[3];\r
3335 pNode[3]->mNext = mQuestionList; \r
3336 mQuestionList = pNode[0];\r
3337\r
3338 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3339 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3340 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3341 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3342\r
3343 return;\r
3344\r
3345 Err:\r
3346 for (Index = 0; Index < 4; Index++) {\r
3347 if (pNode[Index] != NULL) {\r
3348 delete pNode[Index];\r
3349 }\r
3350\r
3351 if (VarIdStr[Index] != NULL) {\r
3352 delete VarIdStr[Index];\r
3353 }\r
3354 }\r
3355}\r
3356\r
30fdf114
LG
3357EFI_VFR_RETURN_CODE\r
3358CVfrQuestionDB::UpdateQuestionId (\r
3359 IN EFI_QUESTION_ID QId,\r
3360 IN EFI_QUESTION_ID NewQId\r
3361 )\r
3362{\r
3363 SVfrQuestionNode *pNode = NULL;\r
3364 \r
3365 if (QId == NewQId) {\r
3366 // don't update\r
3367 return VFR_RETURN_SUCCESS;\r
3368 }\r
3369 \r
3370 //\r
3371 // For Framework Vfr, don't check question ID conflict.\r
3372 // \r
3373 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
3374 return VFR_RETURN_REDEFINED;\r
3375 }\r
3376\r
3377 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3378 if (pNode->mQuestionId == QId) {\r
3379 break;\r
3380 }\r
3381 }\r
3382\r
3383 if (pNode == NULL) {\r
3384 return VFR_RETURN_UNDEFINED;\r
3385 }\r
3386\r
3387 MarkQuestionIdUnused (QId);\r
3388 pNode->mQuestionId = NewQId;\r
3389 MarkQuestionIdUsed (NewQId);\r
3390\r
3391 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
3392\r
3393 return VFR_RETURN_SUCCESS;\r
3394}\r
3395\r
3396VOID\r
3397CVfrQuestionDB::GetQuestionId (\r
3398 IN CHAR8 *Name,\r
3399 IN CHAR8 *VarIdStr,\r
3400 OUT EFI_QUESTION_ID &QuestionId,\r
52302d4d
LG
3401 OUT UINT32 &BitMask,\r
3402 OUT EFI_QUESION_TYPE *QType\r
30fdf114
LG
3403 )\r
3404{\r
3405 SVfrQuestionNode *pNode;\r
3406\r
3407 QuestionId = EFI_QUESTION_ID_INVALID;\r
3408 BitMask = 0x00000000;\r
52302d4d
LG
3409 if (QType != NULL) {\r
3410 *QType = QUESTION_NORMAL;\r
3411 }\r
30fdf114
LG
3412\r
3413 if ((Name == NULL) && (VarIdStr == NULL)) {\r
3414 return ;\r
3415 }\r
3416\r
3417 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3418 if (Name != NULL) {\r
3419 if (strcmp (pNode->mName, Name) != 0) {\r
3420 continue;\r
3421 }\r
3422 }\r
3423\r
3424 if (VarIdStr != NULL) {\r
3425 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
3426 continue;\r
3427 }\r
3428 }\r
3429\r
3430 QuestionId = pNode->mQuestionId;\r
3431 BitMask = pNode->mBitMask;\r
52302d4d
LG
3432 if (QType != NULL) {\r
3433 *QType = pNode->mQtype;\r
3434 }\r
30fdf114
LG
3435 break;\r
3436 }\r
3437\r
3438 return ;\r
3439}\r
3440\r
3441EFI_VFR_RETURN_CODE\r
3442CVfrQuestionDB::FindQuestion (\r
3443 IN EFI_QUESTION_ID QuestionId\r
3444 )\r
3445{\r
3446 SVfrQuestionNode *pNode;\r
3447\r
3448 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3449 return VFR_RETURN_INVALID_PARAMETER;\r
3450 }\r
3451\r
3452 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3453 if (pNode->mQuestionId == QuestionId) {\r
3454 return VFR_RETURN_SUCCESS;\r
3455 }\r
3456 }\r
3457\r
3458 return VFR_RETURN_UNDEFINED;\r
3459}\r
3460\r
3461EFI_VFR_RETURN_CODE\r
3462CVfrQuestionDB::FindQuestion (\r
3463 IN CHAR8 *Name\r
3464 )\r
3465{\r
3466 SVfrQuestionNode *pNode;\r
3467\r
3468 if (Name == NULL) {\r
3469 return VFR_RETURN_FATAL_ERROR;\r
3470 }\r
3471\r
3472 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3473 if (strcmp (pNode->mName, Name) == 0) {\r
3474 return VFR_RETURN_SUCCESS;\r
3475 }\r
3476 }\r
3477\r
3478 return VFR_RETURN_UNDEFINED;\r
3479}\r
3480\r
4234283c
LG
3481CVfrStringDB::CVfrStringDB ()\r
3482{\r
3483 mStringFileName = NULL;\r
3484}\r
3485\r
3486CVfrStringDB::~CVfrStringDB ()\r
3487{\r
3488 if (mStringFileName != NULL) {\r
3489 delete mStringFileName;\r
3490 }\r
3491 mStringFileName = NULL;\r
3492}\r
3493\r
3494\r
3495VOID \r
3496CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
3497{\r
3498 UINT32 FileLen = 0;\r
3499\r
3500 if (StringFileName == NULL) {\r
3501 return;\r
3502 }\r
3503\r
3504 FileLen = strlen (StringFileName) + 1;\r
3505 mStringFileName = new CHAR8[FileLen];\r
3506 if (mStringFileName == NULL) {\r
3507 return;\r
3508 }\r
3509\r
3510 strcpy (mStringFileName, StringFileName);\r
3511 mStringFileName[FileLen - 1] = '\0';\r
3512}\r
3513\r
64b2609f
LG
3514\r
3515/**\r
3516 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language \r
3517 from a set of supported languages.\r
3518\r
3519 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that\r
3520 contains a set of language codes.\r
3521 @param[in] Language A variable that contains pointers to Null-terminated\r
3522 ASCII strings that contain one language codes.\r
3523\r
3524 @retval FALSE The best matching language could not be found in SupportedLanguages.\r
3525 @retval TRUE The best matching language could be found in SupportedLanguages.\r
3526\r
3527**/\r
3528BOOLEAN\r
3529CVfrStringDB::GetBestLanguage (\r
3530 IN CONST CHAR8 *SupportedLanguages,\r
3531 IN CHAR8 *Language\r
3532 )\r
3533{\r
3534 UINTN CompareLength;\r
3535 UINTN LanguageLength;\r
3536 CONST CHAR8 *Supported;\r
3537\r
3538 if (SupportedLanguages == NULL || Language == NULL){\r
3539 return FALSE;\r
3540 }\r
3541\r
3542 //\r
3543 // Determine the length of the first RFC 4646 language code in Language\r
3544 //\r
3545 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
3546\r
3547 //\r
3548 // Trim back the length of Language used until it is empty\r
3549 //\r
3550 while (LanguageLength > 0) {\r
3551 //\r
3552 // Loop through all language codes in SupportedLanguages\r
3553 //\r
3554 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
3555 //\r
3556 // Skip ';' characters in Supported\r
3557 //\r
3558 for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
3559 //\r
3560 // Determine the length of the next language code in Supported\r
3561 //\r
3562 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
3563 //\r
3564 // If Language is longer than the Supported, then skip to the next language\r
3565 //\r
3566 if (LanguageLength > CompareLength) {\r
3567 continue;\r
3568 }\r
3569\r
3570 //\r
3571 // See if the first LanguageLength characters in Supported match Language\r
3572 //\r
3573 if (strncmp (Supported, Language, LanguageLength) == 0) {\r
3574 return TRUE;\r
3575 }\r
3576 }\r
3577\r
3578 //\r
3579 // Trim Language from the right to the next '-' character \r
3580 //\r
3581 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
3582 }\r
3583\r
3584 //\r
3585 // No matches were found \r
3586 //\r
3587 return FALSE;\r
3588}\r
3589\r
3590\r
4234283c
LG
3591CHAR8 *\r
3592CVfrStringDB::GetVarStoreNameFormStringId (\r
3593 IN EFI_STRING_ID StringId\r
3594 )\r
3595{\r
3596 FILE *pInFile = NULL;\r
3597 UINT32 NameOffset;\r
3598 UINT32 Length;\r
3599 UINT8 *StringPtr;\r
3600 CHAR8 *StringName;\r
3601 CHAR16 *UnicodeString;\r
3602 CHAR8 *VarStoreName = NULL;\r
3603 CHAR8 *DestTmp;\r
3604 UINT8 *Current;\r
3605 EFI_STATUS Status;\r
3606 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];\r
3607 UINT8 BlockType;\r
3608 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
3609 \r
d37fa01f 3610 if (mStringFileName == NULL) {\r
4234283c
LG
3611 return NULL;\r
3612 }\r
3613\r
1be2ed90 3614 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {\r
4234283c
LG
3615 return NULL;\r
3616 }\r
3617\r
3618 //\r
3619 // Get file length.\r
3620 //\r
3621 fseek (pInFile, 0, SEEK_END);\r
3622 Length = ftell (pInFile);\r
3623 fseek (pInFile, 0, SEEK_SET);\r
3624\r
3625 //\r
3626 // Get file data.\r
3627 //\r
3628 StringPtr = new UINT8[Length];\r
3629 if (StringPtr == NULL) {\r
3630 fclose (pInFile);\r
3631 return NULL;\r
3632 }\r
3633 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
3634 fclose (pInFile);\r
3635\r
3636 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
3637 //\r
3638 // Check the String package.\r
3639 //\r
3640 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
fd542523 3641 delete[] StringPtr;\r
4234283c
LG
3642 return NULL;\r
3643 }\r
3644\r
3645 //\r
64b2609f 3646 // Search the language, get best language base on RFC 4647 matching algorithm.\r
4234283c
LG
3647 //\r
3648 Current = StringPtr;\r
64b2609f 3649 while (!GetBestLanguage ("en", PkgHeader->Language)) {\r
4234283c
LG
3650 Current += PkgHeader->Header.Length;\r
3651 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
3652 //\r
64b2609f 3653 // If can't find string package base on language, just return the first string package.\r
4234283c
LG
3654 //\r
3655 if (Current - StringPtr >= Length) {\r
3656 Current = StringPtr;\r
64b2609f 3657 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
4234283c
LG
3658 break;\r
3659 }\r
3660 }\r
3661\r
3662 Current += PkgHeader->HdrSize;\r
3663 //\r
3664 // Find the string block according the stringId.\r
3665 //\r
3666 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
3667 if (Status != EFI_SUCCESS) {\r
fd542523 3668 delete[] StringPtr;\r
4234283c
LG
3669 return NULL;\r
3670 }\r
3671\r
3672 //\r
3673 // Get varstore name according the string type.\r
3674 //\r
3675 switch (BlockType) {\r
3676 case EFI_HII_SIBT_STRING_SCSU:\r
3677 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3678 case EFI_HII_SIBT_STRINGS_SCSU:\r
3679 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3680 StringName = (CHAR8*)(Current + NameOffset);\r
3681 VarStoreName = new CHAR8[strlen(StringName) + 1];\r
3682 strcpy (VarStoreName, StringName);\r
3683 break;\r
3684 case EFI_HII_SIBT_STRING_UCS2:\r
3685 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3686 case EFI_HII_SIBT_STRINGS_UCS2:\r
3687 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3688 UnicodeString = (CHAR16*)(Current + NameOffset);\r
3689 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
3690 DestTmp = new CHAR8[Length / 2 + 1];\r
3691 VarStoreName = DestTmp;\r
3692 while (*UnicodeString != '\0') {\r
3693 *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
3694 }\r
3695 *DestTmp = '\0';\r
3696 break;\r
3697 default:\r
3698 break;\r
3699 }\r
3700\r
fd542523 3701 delete[] StringPtr;\r
4234283c
LG
3702\r
3703 return VarStoreName;\r
3704}\r
3705\r
3706EFI_STATUS\r
3707CVfrStringDB::FindStringBlock (\r
3708 IN UINT8 *StringData,\r
3709 IN EFI_STRING_ID StringId,\r
3710 OUT UINT32 *StringTextOffset,\r
3711 OUT UINT8 *BlockType\r
3712 )\r
3713{\r
3714 UINT8 *BlockHdr;\r
3715 EFI_STRING_ID CurrentStringId;\r
3716 UINT32 BlockSize;\r
3717 UINT32 Index;\r
3718 UINT8 *StringTextPtr;\r
3719 UINT32 Offset;\r
3720 UINT16 StringCount;\r
3721 UINT16 SkipCount;\r
3722 UINT8 Length8;\r
3723 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
3724 UINT32 Length32;\r
3725 UINT32 StringSize;\r
3726\r
3727 CurrentStringId = 1;\r
3728\r
3729 //\r
3730 // Parse the string blocks to get the string text and font.\r
3731 //\r
3732 BlockHdr = StringData;\r
3733 BlockSize = 0;\r
3734 Offset = 0;\r
3735 while (*BlockHdr != EFI_HII_SIBT_END) {\r
3736 switch (*BlockHdr) {\r
3737 case EFI_HII_SIBT_STRING_SCSU:\r
3738 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3739 StringTextPtr = BlockHdr + Offset;\r
3740 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3741 CurrentStringId++;\r
3742 break;\r
3743\r
3744 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3745 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3746 StringTextPtr = BlockHdr + Offset;\r
3747 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3748 CurrentStringId++;\r
3749 break;\r
3750\r
3751 case EFI_HII_SIBT_STRINGS_SCSU:\r
3752 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3753 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
3754 BlockSize += StringTextPtr - BlockHdr;\r
3755\r
3756 for (Index = 0; Index < StringCount; Index++) {\r
3757 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3758 if (CurrentStringId == StringId) {\r
3759 *BlockType = *BlockHdr;\r
3760 *StringTextOffset = StringTextPtr - StringData;\r
3761 return EFI_SUCCESS;\r
3762 }\r
3763 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3764 CurrentStringId++;\r
3765 }\r
3766 break;\r
3767\r
3768 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3769 memcpy (\r
3770 &StringCount,\r
3771 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3772 sizeof (UINT16)\r
3773 );\r
3774 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3775 BlockSize += StringTextPtr - BlockHdr;\r
3776\r
3777 for (Index = 0; Index < StringCount; Index++) {\r
3778 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3779 if (CurrentStringId == StringId) {\r
3780 *BlockType = *BlockHdr;\r
3781 *StringTextOffset = StringTextPtr - StringData;\r
3782 return EFI_SUCCESS;\r
3783 }\r
3784 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3785 CurrentStringId++;\r
3786 }\r
3787 break;\r
3788\r
3789 case EFI_HII_SIBT_STRING_UCS2:\r
3790 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3791 StringTextPtr = BlockHdr + Offset;\r
3792 //\r
3793 // Use StringSize to store the size of the specified string, including the NULL\r
3794 // terminator.\r
3795 //\r
3796 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3797 BlockSize += Offset + StringSize;\r
3798 CurrentStringId++;\r
3799 break;\r
3800\r
3801 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3802 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3803 StringTextPtr = BlockHdr + Offset;\r
3804 //\r
3805 // Use StrSize to store the size of the specified string, including the NULL\r
3806 // terminator.\r
3807 //\r
3808 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3809 BlockSize += Offset + StringSize;\r
3810 CurrentStringId++;\r
3811 break;\r
3812\r
3813 case EFI_HII_SIBT_STRINGS_UCS2:\r
3814 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
3815 StringTextPtr = BlockHdr + Offset;\r
3816 BlockSize += Offset;\r
3817 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3818 for (Index = 0; Index < StringCount; Index++) {\r
3819 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3820 BlockSize += StringSize;\r
3821 if (CurrentStringId == StringId) {\r
3822 *BlockType = *BlockHdr;\r
3823 *StringTextOffset = StringTextPtr - StringData;\r
3824 return EFI_SUCCESS;\r
3825 }\r
3826 StringTextPtr = StringTextPtr + StringSize;\r
3827 CurrentStringId++;\r
3828 }\r
3829 break;\r
3830\r
3831 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3832 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3833 StringTextPtr = BlockHdr + Offset;\r
3834 BlockSize += Offset;\r
3835 memcpy (\r
3836 &StringCount,\r
3837 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3838 sizeof (UINT16)\r
3839 );\r
3840 for (Index = 0; Index < StringCount; Index++) {\r
3841 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3842 BlockSize += StringSize;\r
3843 if (CurrentStringId == StringId) {\r
3844 *BlockType = *BlockHdr;\r
3845 *StringTextOffset = StringTextPtr - StringData;\r
3846 return EFI_SUCCESS;\r
3847 }\r
3848 StringTextPtr = StringTextPtr + StringSize;\r
3849 CurrentStringId++;\r
3850 }\r
3851 break;\r
3852\r
3853 case EFI_HII_SIBT_DUPLICATE:\r
3854 if (CurrentStringId == StringId) {\r
3855 //\r
3856 // Incoming StringId is an id of a duplicate string block.\r
3857 // Update the StringId to be the previous string block.\r
3858 // Go back to the header of string block to search.\r
3859 //\r
3860 memcpy (\r
3861 &StringId,\r
3862 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
3863 sizeof (EFI_STRING_ID)\r
3864 );\r
3865 CurrentStringId = 1;\r
3866 BlockSize = 0;\r
3867 } else {\r
3868 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
3869 CurrentStringId++;\r
3870 }\r
3871 break;\r
3872\r
3873 case EFI_HII_SIBT_SKIP1:\r
3874 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
3875 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3876 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
3877 break;\r
3878\r
3879 case EFI_HII_SIBT_SKIP2:\r
3880 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3881 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3882 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
3883 break;\r
3884\r
3885 case EFI_HII_SIBT_EXT1:\r
3886 memcpy (\r
3887 &Length8,\r
3888 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3889 sizeof (UINT8)\r
3890 );\r
3891 BlockSize += Length8;\r
3892 break;\r
3893\r
3894 case EFI_HII_SIBT_EXT2:\r
3895 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
3896 BlockSize += Ext2.Length;\r
3897 break;\r
3898\r
3899 case EFI_HII_SIBT_EXT4:\r
3900 memcpy (\r
3901 &Length32,\r
3902 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3903 sizeof (UINT32)\r
3904 );\r
3905\r
3906 BlockSize += Length32;\r
3907 break;\r
3908\r
3909 default:\r
3910 break;\r
3911 }\r
3912\r
3913 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
3914 *StringTextOffset = BlockHdr - StringData + Offset;\r
3915 *BlockType = *BlockHdr;\r
3916\r
3917 if (StringId == CurrentStringId - 1) {\r
3918 //\r
3919 // if only one skip item, return EFI_NOT_FOUND.\r
3920 //\r
3921 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
3922 return EFI_NOT_FOUND;\r
3923 } else {\r
3924 return EFI_SUCCESS;\r
3925 }\r
3926 }\r
3927\r
3928 if (StringId < CurrentStringId - 1) {\r
3929 return EFI_NOT_FOUND;\r
3930 }\r
3931 }\r
3932 BlockHdr = StringData + BlockSize;\r
3933 }\r
3934\r
3935 return EFI_NOT_FOUND;\r
3936}\r
3937\r
3938UINT32\r
3939CVfrStringDB::GetUnicodeStringTextSize (\r
3940 IN UINT8 *StringSrc\r
3941 )\r
3942{\r
3943 UINT32 StringSize;\r
3944 CHAR16 *StringPtr;\r
3945\r
3946 StringSize = sizeof (CHAR16);\r
3947 StringPtr = (UINT16*)StringSrc;\r
3948 while (*StringPtr++ != L'\0') {\r
3949 StringSize += sizeof (CHAR16);\r
3950 }\r
3951\r
3952 return StringSize;\r
3953}\r
3954\r
30fdf114
LG
3955BOOLEAN VfrCompatibleMode = FALSE;\r
3956\r
3957CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
74bbe31b
DB
3958CVfrDefaultStore gCVfrDefaultStore;\r
3959CVfrDataStorage gCVfrDataStorage;\r
30fdf114 3960\r
52302d4d 3961\r