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