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