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