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