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