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