]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools/TianoCompress: Add checks for array access
[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
126 BUFFER_SAFE_FREE (mValue);\r
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
203 BUFFER_SAFE_FREE (mName);\r
4afd3d04 204 BUFFER_SAFE_FREE (mGuid);\r
30fdf114
LG
205 BUFFER_SAFE_FREE (mId);\r
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
1396 delete mVarStoreName;\r
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
1477 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
1478 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
1479 mFreeVarStoreIdBitMap[Index] |= Mask;\r
1480 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
1481 }\r
1482 }\r
1483\r
1484 return EFI_VARSTORE_ID_INVALID;\r
1485}\r
1486\r
1487BOOLEAN\r
1488CVfrDataStorage::ChekVarStoreIdFree (\r
1489 IN EFI_VARSTORE_ID VarStoreId\r
1490 )\r
1491{\r
1492 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1493 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1494\r
1495 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
1496}\r
1497\r
1498VOID\r
1499CVfrDataStorage::MarkVarStoreIdUsed (\r
1500 IN EFI_VARSTORE_ID VarStoreId\r
1501 )\r
1502{\r
1503 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1504 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1505\r
1506 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
1507}\r
1508\r
1509VOID\r
1510CVfrDataStorage::MarkVarStoreIdUnused (\r
1511 IN EFI_VARSTORE_ID VarStoreId\r
1512 )\r
1513{\r
1514 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);\r
1515 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1516\r
1517 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
1518}\r
1519\r
1520EFI_VFR_RETURN_CODE\r
1521CVfrDataStorage::DeclareNameVarStoreBegin (\r
e8a47801
LG
1522 IN CHAR8 *StoreName,\r
1523 IN EFI_VARSTORE_ID VarStoreId\r
30fdf114
LG
1524 )\r
1525{\r
1526 SVfrVarStorageNode *pNode = NULL;\r
e8a47801 1527 EFI_VARSTORE_ID TmpVarStoreId;\r
30fdf114
LG
1528\r
1529 if (StoreName == NULL) {\r
1530 return VFR_RETURN_FATAL_ERROR;\r
1531 }\r
1532\r
e8a47801 1533 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {\r
da92f276 1534 return VFR_RETURN_REDEFINED;\r
30fdf114 1535 }\r
e8a47801
LG
1536 \r
1537 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1538 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
1539 } else {\r
1540 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1541 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1542 }\r
1543 MarkVarStoreIdUsed (VarStoreId);\r
1544 }\r
30fdf114 1545\r
30fdf114
LG
1546 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
1547 return VFR_RETURN_UNDEFINED;\r
1548 }\r
1549\r
1550 mNewVarStorageNode = pNode;\r
1551\r
1552 return VFR_RETURN_SUCCESS;\r
1553}\r
1554\r
1555EFI_VFR_RETURN_CODE\r
1556CVfrDataStorage::NameTableAddItem (\r
1557 IN EFI_STRING_ID Item\r
1558 )\r
1559{\r
1560 EFI_VARSTORE_ID *NewTable, *OldTable;\r
1561 UINT32 TableSize;\r
1562\r
1563 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
1564 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
1565\r
1566 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
1567 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
1568 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1569 }\r
1570 memcpy (NewTable, OldTable, TableSize);\r
1571 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
1572 }\r
1573\r
1574 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
1575 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
1576\r
1577 return VFR_RETURN_SUCCESS;\r
1578}\r
1579\r
1580EFI_VFR_RETURN_CODE\r
1581CVfrDataStorage::DeclareNameVarStoreEnd (\r
1582 IN EFI_GUID *Guid\r
1583 )\r
1584{\r
1585 mNewVarStorageNode->mGuid = *Guid;\r
1586 mNewVarStorageNode->mNext = mNameVarStoreList;\r
1587 mNameVarStoreList = mNewVarStorageNode;\r
1588\r
1589 mNewVarStorageNode = NULL;\r
1590\r
1591 return VFR_RETURN_SUCCESS;\r
1592}\r
1593\r
1594EFI_VFR_RETURN_CODE \r
1595CVfrDataStorage::DeclareEfiVarStore (\r
1596 IN CHAR8 *StoreName, \r
1597 IN EFI_GUID *Guid, \r
1598 IN EFI_STRING_ID NameStrId,\r
1599 IN UINT32 VarSize,\r
1600 IN BOOLEAN Flag\r
1601 )\r
1602{\r
1603 SVfrVarStorageNode *pNode;\r
1604 EFI_VARSTORE_ID VarStoreId;\r
1605\r
1606 if ((StoreName == NULL) || (Guid == NULL)) {\r
1607 return VFR_RETURN_FATAL_ERROR;\r
1608 }\r
1609\r
1610 if (VarSize > sizeof (UINT64)) {\r
1611 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
1612 }\r
1613\r
4afd3d04 1614 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
da92f276 1615 return VFR_RETURN_REDEFINED;\r
30fdf114
LG
1616 }\r
1617\r
1618 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
1619 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {\r
1620 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1621 }\r
1622\r
1623 pNode->mNext = mEfiVarStoreList;\r
1624 mEfiVarStoreList = pNode;\r
1625\r
1626 return VFR_RETURN_SUCCESS;\r
1627}\r
1628\r
1629EFI_VFR_RETURN_CODE \r
1630CVfrDataStorage::DeclareBufferVarStore (\r
1631 IN CHAR8 *StoreName, \r
1632 IN EFI_GUID *Guid, \r
1633 IN CVfrVarDataTypeDB *DataTypeDB,\r
1634 IN CHAR8 *TypeName,\r
1635 IN EFI_VARSTORE_ID VarStoreId,\r
1636 IN BOOLEAN Flag\r
1637 )\r
1638{\r
1639 SVfrVarStorageNode *pNew = NULL;\r
1640 SVfrDataType *pDataType = NULL;\r
da92f276 1641 EFI_VARSTORE_ID TempVarStoreId;\r
30fdf114
LG
1642\r
1643 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1644 return VFR_RETURN_FATAL_ERROR;\r
1645 }\r
1646\r
4afd3d04 1647 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
da92f276
LG
1648 return VFR_RETURN_REDEFINED;\r
1649 }\r
1650\r
30fdf114
LG
1651 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
1652\r
1653 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1654 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);\r
1655 } else {\r
1656 if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1657 return VFR_RETURN_VARSTOREID_REDEFINED;\r
1658 }\r
1659 MarkVarStoreIdUsed (VarStoreId);\r
1660 }\r
1661\r
1662 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
1663 return VFR_RETURN_OUT_FOR_RESOURCES;\r
1664 }\r
1665\r
1666 pNew->mNext = mBufferVarStoreList;\r
1667 mBufferVarStoreList = pNew;\r
1668\r
4afd3d04 1669 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {\r
30fdf114
LG
1670 return VFR_RETURN_FATAL_ERROR;\r
1671 }\r
1672\r
1673 return VFR_RETURN_SUCCESS;\r
1674}\r
1675\r
da92f276
LG
1676EFI_VFR_RETURN_CODE \r
1677CVfrDataStorage::GetVarStoreByDataType (\r
1678 IN CHAR8 *DataTypeName,\r
4afd3d04
LG
1679 OUT SVfrVarStorageNode **VarNode,\r
1680 IN EFI_GUID *VarGuid\r
da92f276
LG
1681 )\r
1682{\r
1683 SVfrVarStorageNode *pNode;\r
1684 SVfrVarStorageNode *MatchNode;\r
1685 \r
1686 //\r
1687 // Framework VFR uses Data type name as varstore name, so don't need check again.\r
1688 //\r
1689 if (VfrCompatibleMode) {\r
1690 return VFR_RETURN_UNDEFINED;\r
1691 }\r
1692\r
1693 MatchNode = NULL;\r
1694 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04
LG
1695 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {\r
1696 continue;\r
1697 }\r
1698\r
1699 if ((VarGuid != NULL)) {\r
1700 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
1701 *VarNode = pNode;\r
1702 return VFR_RETURN_SUCCESS;\r
1703 }\r
1704 } else {\r
da92f276
LG
1705 if (MatchNode == NULL) {\r
1706 MatchNode = pNode;\r
1707 } else {\r
1708 //\r
1709 // More than one varstores referred the same data structures.\r
1710 //\r
1711 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;\r
1712 }\r
1713 }\r
1714 }\r
1715 \r
1716 if (MatchNode == NULL) {\r
1717 return VFR_RETURN_UNDEFINED;\r
1718 }\r
1719\r
1720 *VarNode = MatchNode;\r
1721 return VFR_RETURN_SUCCESS;\r
1722}\r
1723\r
4afd3d04
LG
1724EFI_VARSTORE_ID \r
1725CVfrDataStorage::CheckGuidField (\r
1726 IN SVfrVarStorageNode *pNode,\r
1727 IN EFI_GUID *StoreGuid,\r
1728 IN BOOLEAN *HasFoundOne,\r
1729 OUT EFI_VFR_RETURN_CODE *ReturnCode\r
1730 )\r
1731{\r
1732 if (StoreGuid != NULL) {\r
1733 //\r
1734 // If has guid info, compare the guid filed.\r
1735 //\r
1736 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
1737 //\r
1738 // Both name and guid are same, this this varstore.\r
1739 //\r
1740 mCurrVarStorageNode = pNode;\r
1741 *ReturnCode = VFR_RETURN_SUCCESS;\r
1742 return TRUE;\r
1743 }\r
1744 } else {\r
1745 //\r
1746 // Not has Guid field, check whether this name is the only one.\r
1747 //\r
1748 if (*HasFoundOne) {\r
1749 //\r
1750 // The name has conflict, return name redefined.\r
1751 //\r
1752 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;\r
1753 return TRUE;\r
1754 }\r
1755\r
1756 *HasFoundOne = TRUE;\r
1757 mCurrVarStorageNode = pNode;\r
1758 }\r
1759\r
1760 return FALSE;\r
1761}\r
1762\r
1763/**\r
1764 Base on the input store name and guid to find the varstore id. \r
1765\r
1766 If both name and guid are inputed, base on the name and guid to\r
1767 found the varstore. If only name inputed, base on the name to\r
1768 found the varstore and go on to check whether more than one varstore\r
1769 has the same name. If only has found one varstore, return this\r
1770 varstore; if more than one varstore has same name, return varstore\r
1771 name redefined error. If no varstore found by varstore name, call\r
1772 function GetVarStoreByDataType and use inputed varstore name as \r
1773 data type name to search.\r
1774**/\r
30fdf114
LG
1775EFI_VFR_RETURN_CODE \r
1776CVfrDataStorage::GetVarStoreId (\r
1777 IN CHAR8 *StoreName,\r
4afd3d04
LG
1778 OUT EFI_VARSTORE_ID *VarStoreId,\r
1779 IN EFI_GUID *StoreGuid\r
30fdf114
LG
1780 )\r
1781{\r
da92f276 1782 EFI_VFR_RETURN_CODE ReturnCode;\r
30fdf114 1783 SVfrVarStorageNode *pNode;\r
4afd3d04
LG
1784 BOOLEAN HasFoundOne = FALSE;\r
1785\r
1786 mCurrVarStorageNode = NULL;\r
30fdf114
LG
1787\r
1788 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1789 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
1790 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
1791 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
1792 return ReturnCode;\r
1793 }\r
30fdf114
LG
1794 }\r
1795 }\r
1796\r
1797 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1798 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
1799 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
1800 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
1801 return ReturnCode;\r
1802 }\r
30fdf114
LG
1803 }\r
1804 }\r
1805\r
1806 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1807 if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
4afd3d04
LG
1808 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
1809 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
1810 return ReturnCode;\r
1811 }\r
30fdf114
LG
1812 }\r
1813 }\r
1814\r
4afd3d04
LG
1815 if (HasFoundOne) {\r
1816 *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
1817 return VFR_RETURN_SUCCESS;\r
1818 }\r
1819\r
da92f276
LG
1820 *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
1821\r
1822 //\r
1823 // Assume that Data strucutre name is used as StoreName, and check again. \r
1824 //\r
4afd3d04 1825 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
da92f276
LG
1826 if (pNode != NULL) {\r
1827 mCurrVarStorageNode = pNode;\r
1828 *VarStoreId = pNode->mVarStoreId;\r
1829 }\r
1830 \r
1831 return ReturnCode;\r
30fdf114
LG
1832}\r
1833\r
1834EFI_VFR_RETURN_CODE\r
1835CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
4afd3d04 1836 IN EFI_VARSTORE_ID VarStoreId,\r
30fdf114
LG
1837 OUT CHAR8 **DataTypeName\r
1838 )\r
1839{\r
1840 SVfrVarStorageNode *pNode;\r
1841\r
4afd3d04 1842 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
30fdf114
LG
1843 return VFR_RETURN_FATAL_ERROR;\r
1844 }\r
1845\r
1846 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04
LG
1847 if (pNode->mVarStoreId == VarStoreId) {\r
1848 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
1849 return VFR_RETURN_SUCCESS;\r
30fdf114
LG
1850 }\r
1851 }\r
1852\r
4afd3d04 1853 return VFR_RETURN_UNDEFINED;\r
30fdf114
LG
1854}\r
1855\r
4afd3d04 1856EFI_VFR_VARSTORE_TYPE\r
30fdf114 1857CVfrDataStorage::GetVarStoreType (\r
4afd3d04 1858 IN EFI_VARSTORE_ID VarStoreId\r
30fdf114
LG
1859 )\r
1860{\r
1861 SVfrVarStorageNode *pNode;\r
4afd3d04 1862 EFI_VFR_VARSTORE_TYPE VarStoreType;\r
30fdf114 1863\r
4afd3d04
LG
1864 VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1865\r
1866 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1867 return VarStoreType;\r
30fdf114
LG
1868 }\r
1869\r
1870 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 1871 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 1872 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 1873 return VarStoreType;\r
30fdf114
LG
1874 }\r
1875 }\r
1876\r
1877 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 1878 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 1879 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 1880 return VarStoreType;\r
30fdf114
LG
1881 }\r
1882 }\r
1883\r
1884 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
4afd3d04 1885 if (pNode->mVarStoreId == VarStoreId) {\r
30fdf114 1886 VarStoreType = pNode->mVarStoreType;\r
4afd3d04 1887 return VarStoreType;\r
30fdf114
LG
1888 }\r
1889 }\r
1890\r
4afd3d04 1891 return VarStoreType;\r
30fdf114
LG
1892}\r
1893\r
4afd3d04
LG
1894EFI_GUID *\r
1895CVfrDataStorage::GetVarStoreGuid (\r
30fdf114
LG
1896 IN EFI_VARSTORE_ID VarStoreId\r
1897 )\r
1898{\r
1899 SVfrVarStorageNode *pNode;\r
4afd3d04 1900 EFI_GUID *VarGuid;\r
30fdf114 1901\r
4afd3d04 1902 VarGuid = NULL;\r
30fdf114
LG
1903\r
1904 if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
4afd3d04 1905 return VarGuid;\r
30fdf114
LG
1906 }\r
1907\r
1908 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1909 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
1910 VarGuid = &pNode->mGuid;\r
1911 return VarGuid;\r
30fdf114
LG
1912 }\r
1913 }\r
1914\r
1915 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1916 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
1917 VarGuid = &pNode->mGuid;\r
1918 return VarGuid;\r
30fdf114
LG
1919 }\r
1920 }\r
1921\r
1922 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1923 if (pNode->mVarStoreId == VarStoreId) {\r
4afd3d04
LG
1924 VarGuid = &pNode->mGuid;\r
1925 return VarGuid;\r
30fdf114
LG
1926 }\r
1927 }\r
1928\r
4afd3d04 1929 return VarGuid;\r
30fdf114
LG
1930}\r
1931\r
1932EFI_VFR_RETURN_CODE\r
1933CVfrDataStorage::GetVarStoreName (\r
1934 IN EFI_VARSTORE_ID VarStoreId, \r
1935 OUT CHAR8 **VarStoreName\r
1936 )\r
1937{\r
1938 SVfrVarStorageNode *pNode;\r
1939\r
1940 if (VarStoreName == NULL) {\r
1941 return VFR_RETURN_FATAL_ERROR;\r
1942 }\r
1943\r
1944 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1945 if (pNode->mVarStoreId == VarStoreId) {\r
1946 *VarStoreName = pNode->mVarStoreName;\r
1947 return VFR_RETURN_SUCCESS;\r
1948 }\r
1949 }\r
1950\r
1951 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1952 if (pNode->mVarStoreId == VarStoreId) {\r
1953 *VarStoreName = pNode->mVarStoreName;\r
1954 return VFR_RETURN_SUCCESS;\r
1955 }\r
1956 }\r
1957\r
1958 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1959 if (pNode->mVarStoreId == VarStoreId) {\r
1960 *VarStoreName = pNode->mVarStoreName;\r
1961 return VFR_RETURN_SUCCESS;\r
1962 }\r
1963 }\r
1964\r
1965 *VarStoreName = NULL;\r
1966 return VFR_RETURN_UNDEFINED;\r
1967}\r
1968\r
1969EFI_VFR_RETURN_CODE\r
1970CVfrDataStorage::GetEfiVarStoreInfo (\r
1971 IN OUT EFI_VARSTORE_INFO *Info\r
1972 )\r
1973{\r
1974 if (Info == NULL) {\r
1975 return VFR_RETURN_FATAL_ERROR;\r
1976 }\r
1977\r
1978 if (mCurrVarStorageNode == NULL) {\r
1979 return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
1980 }\r
1981\r
1982 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
1983 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
1984 switch (Info->mVarTotalSize) {\r
1985 case 1:\r
1986 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
1987 break;\r
1988 case 2:\r
1989 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
1990 break;\r
1991 case 4:\r
1992 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
1993 break;\r
1994 case 8:\r
1995 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
1996 break;\r
1997 default :\r
1998 return VFR_RETURN_FATAL_ERROR;\r
1999 }\r
2000\r
2001 return VFR_RETURN_SUCCESS;\r
2002}\r
2003\r
74bbe31b
DB
2004EFI_VFR_RETURN_CODE\r
2005CVfrDataStorage::AddBufferVarStoreFieldInfo (\r
2006 IN EFI_VARSTORE_INFO *Info\r
2007 )\r
2008{\r
2009 BufferVarStoreFieldInfoNode *pNew;\r
2010\r
2011 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {\r
2012 return VFR_RETURN_FATAL_ERROR;\r
2013 }\r
2014\r
2015 if (mBufferFieldInfoListHead == NULL) {\r
2016 mBufferFieldInfoListHead = pNew;\r
2017 mBufferFieldInfoListTail= pNew;\r
2018 } else {\r
2019 mBufferFieldInfoListTail->mNext = pNew;\r
2020 mBufferFieldInfoListTail = pNew;\r
2021 }\r
2022\r
2023 return VFR_RETURN_SUCCESS;\r
2024}\r
2025\r
2026EFI_VFR_RETURN_CODE\r
2027CVfrDataStorage::GetBufferVarStoreFieldInfo (\r
2028 IN OUT EFI_VARSTORE_INFO *Info\r
2029 )\r
2030{\r
2031 BufferVarStoreFieldInfoNode *pNode;\r
2032\r
2033 pNode = mBufferFieldInfoListHead;\r
2034 while (pNode != NULL) {\r
2035 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&\r
2036 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {\r
2037 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;\r
2038 Info->mVarType = pNode->mVarStoreInfo.mVarType;\r
2039 return VFR_RETURN_SUCCESS;\r
2040 }\r
2041 pNode = pNode->mNext;\r
2042 }\r
2043 return VFR_RETURN_FATAL_ERROR;\r
2044}\r
2045\r
30fdf114
LG
2046EFI_VFR_RETURN_CODE\r
2047CVfrDataStorage::GetNameVarStoreInfo (\r
2048 OUT EFI_VARSTORE_INFO *Info,\r
2049 IN UINT32 Index\r
2050 )\r
2051{\r
2052 if (Info == NULL) {\r
2053 return VFR_RETURN_FATAL_ERROR;\r
2054 }\r
2055\r
2056 if (mCurrVarStorageNode == NULL) {\r
2057 return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
2058 }\r
2059 \r
2060 //\r
2061 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
2062 //\r
2063 if (VfrCompatibleMode) {\r
2064 if (Index == 0) {\r
2065 return VFR_RETURN_ERROR_ARRARY_NUM;\r
2066 }\r
2067 Index --;\r
2068 }\r
2069\r
2070 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
2071\r
2072 return VFR_RETURN_SUCCESS;\r
2073}\r
2074\r
30fdf114
LG
2075SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
2076 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
2077 IN CHAR8 *RefName, \r
2078 IN EFI_STRING_ID DefaultStoreNameId, \r
2079 IN UINT16 DefaultId\r
2080 )\r
2081{\r
2082 mObjBinAddr = ObjBinAddr;\r
2083\r
2084 if (RefName != NULL) {\r
2085 mRefName = new CHAR8[strlen (RefName) + 1];\r
2086 strcpy (mRefName, RefName);\r
2087 } else {\r
2088 mRefName = NULL;\r
2089 }\r
2090\r
2091 mNext = NULL;\r
2092 mDefaultId = DefaultId;\r
2093 mDefaultStoreNameId = DefaultStoreNameId;\r
2094}\r
2095\r
2096SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
2097 VOID\r
2098 )\r
2099{\r
2100 if (mRefName != NULL) {\r
2101 delete mRefName;\r
2102 }\r
2103}\r
2104\r
2105CVfrDefaultStore::CVfrDefaultStore (\r
2106 VOID\r
2107 )\r
2108{\r
2109 mDefaultStoreList = NULL;\r
2110}\r
2111\r
2112CVfrDefaultStore::~CVfrDefaultStore (\r
2113 VOID\r
2114 )\r
2115{\r
2116 SVfrDefaultStoreNode *pTmp = NULL;\r
2117\r
2118 while (mDefaultStoreList != NULL) {\r
2119 pTmp = mDefaultStoreList;\r
2120 mDefaultStoreList = mDefaultStoreList->mNext;\r
2121 delete pTmp;\r
2122 }\r
2123}\r
2124\r
2125EFI_VFR_RETURN_CODE\r
2126CVfrDefaultStore::RegisterDefaultStore (\r
2127 IN CHAR8 *ObjBinAddr,\r
2128 IN CHAR8 *RefName,\r
2129 IN EFI_STRING_ID DefaultStoreNameId,\r
2130 IN UINT16 DefaultId\r
2131 )\r
2132{\r
2133 SVfrDefaultStoreNode *pNode = NULL;\r
2134\r
2135 if (RefName == NULL) {\r
2136 return VFR_RETURN_FATAL_ERROR;\r
2137 }\r
2138\r
2139 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2140 if (strcmp (pNode->mRefName, RefName) == 0) {\r
2141 return VFR_RETURN_REDEFINED;\r
2142 }\r
2143 }\r
2144\r
2145 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
2146 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2147 }\r
2148\r
2149 pNode->mNext = mDefaultStoreList;\r
2150 mDefaultStoreList = pNode;\r
2151\r
2152 return VFR_RETURN_SUCCESS;\r
2153}\r
2154\r
2155/*\r
2156 * assign new reference name or new default store name id only if \r
2157 * the original is invalid\r
2158 */\r
2159EFI_VFR_RETURN_CODE\r
2160CVfrDefaultStore::ReRegisterDefaultStoreById (\r
2161 IN UINT16 DefaultId,\r
2162 IN CHAR8 *RefName,\r
2163 IN EFI_STRING_ID DefaultStoreNameId\r
2164 )\r
2165{\r
2166 SVfrDefaultStoreNode *pNode = NULL;\r
2167\r
2168 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2169 if (pNode->mDefaultId == DefaultId) {\r
2170 break;\r
2171 }\r
2172 }\r
2173\r
2174 if (pNode == NULL) {\r
2175 return VFR_RETURN_UNDEFINED;\r
2176 } else {\r
2177 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
2178 pNode->mDefaultStoreNameId = DefaultStoreNameId;\r
2179 if (pNode->mObjBinAddr != NULL) {\r
2180 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
2181 }\r
2182 } else {\r
2183 return VFR_RETURN_REDEFINED;\r
2184 }\r
2185\r
2186 if (RefName != NULL) {\r
2187 delete pNode->mRefName;\r
2188 pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
2189 if (pNode->mRefName != NULL) {\r
2190 strcpy (pNode->mRefName, RefName);\r
2191 }\r
2192 }\r
2193 }\r
2194\r
2195 return VFR_RETURN_SUCCESS;\r
2196}\r
2197\r
2198BOOLEAN\r
2199CVfrDefaultStore::DefaultIdRegistered (\r
2200 IN UINT16 DefaultId\r
2201 )\r
2202{\r
2203 SVfrDefaultStoreNode *pNode = NULL;\r
2204\r
2205 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2206 if (pNode->mDefaultId == DefaultId) {\r
2207 return TRUE;\r
2208 }\r
2209 }\r
2210\r
2211 return FALSE;\r
2212}\r
2213\r
2214EFI_VFR_RETURN_CODE\r
2215CVfrDefaultStore::GetDefaultId (\r
2216 IN CHAR8 *RefName,\r
2217 OUT UINT16 *DefaultId\r
2218 )\r
2219{\r
2220 SVfrDefaultStoreNode *pTmp = NULL;\r
2221\r
2222 if (DefaultId == NULL) {\r
2223 return VFR_RETURN_FATAL_ERROR;\r
2224 }\r
2225\r
2226 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
2227 if (strcmp (pTmp->mRefName, RefName) == 0) {\r
2228 *DefaultId = pTmp->mDefaultId;\r
2229 return VFR_RETURN_SUCCESS;\r
2230 }\r
2231 }\r
2232\r
2233 return VFR_RETURN_UNDEFINED;\r
2234}\r
2235\r
30fdf114
LG
2236EFI_VFR_RETURN_CODE\r
2237CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2238 IN EFI_VARSTORE_ID DefaultId,\r
2239 IN EFI_VARSTORE_INFO &Info,\r
2240 IN CHAR8 *VarStoreName,\r
4afd3d04 2241 IN EFI_GUID *VarStoreGuid,\r
30fdf114
LG
2242 IN UINT8 Type,\r
2243 IN EFI_IFR_TYPE_VALUE Value\r
2244 )\r
2245{\r
2246 SVfrDefaultStoreNode *pNode = NULL;\r
2247 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2248 INTN Returnvalue = 0;\r
2249\r
2250 if (VarStoreName == NULL) {\r
2251 return VFR_RETURN_FATAL_ERROR;\r
2252 }\r
2253\r
2254 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2255 if (pNode->mDefaultId == DefaultId) {\r
2256 break;\r
2257 }\r
2258 }\r
2259\r
2260 if (pNode == NULL) {\r
2261 return VFR_RETURN_UNDEFINED;\r
2262 }\r
2263\r
2264 gCVfrBufferConfig.Open ();\r
2265\r
2266 sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
4afd3d04
LG
2267 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {\r
2268 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
30fdf114
LG
2269 goto WriteError;\r
2270 }\r
2271 }\r
2272 \r
2273 gCVfrBufferConfig.Close ();\r
2274\r
2275 return VFR_RETURN_SUCCESS;\r
2276\r
2277WriteError:\r
2278 gCVfrBufferConfig.Close ();\r
2279 return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2280}\r
2281\r
2282SVfrRuleNode::SVfrRuleNode (\r
2283 IN CHAR8 *RuleName,\r
2284 IN UINT8 RuleId\r
2285 )\r
2286{\r
2287 if (RuleName != NULL) {\r
2288 mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2289 strcpy (mRuleName, RuleName);\r
2290 } else {\r
2291 mRuleName = NULL;\r
2292 }\r
2293\r
2294 mNext = NULL;\r
2295 mRuleId = RuleId;\r
2296}\r
2297\r
2298SVfrRuleNode::~SVfrRuleNode (\r
2299 VOID\r
2300 )\r
2301{\r
2302 if (mRuleName != NULL) {\r
2303 delete mRuleName;\r
2304 }\r
2305}\r
2306\r
2307CVfrRulesDB::CVfrRulesDB ()\r
2308{\r
2309 mRuleList = NULL;\r
2310 mFreeRuleId = EFI_VARSTORE_ID_START;\r
2311}\r
2312\r
2313CVfrRulesDB::~CVfrRulesDB ()\r
2314{\r
2315 SVfrRuleNode *pNode;\r
2316\r
2317 while(mRuleList != NULL) {\r
2318 pNode = mRuleList;\r
2319 mRuleList = mRuleList->mNext;\r
2320 delete pNode;\r
2321 }\r
2322}\r
2323\r
2324VOID\r
2325CVfrRulesDB::RegisterRule (\r
2326 IN CHAR8 *RuleName\r
2327 )\r
2328{\r
2329 SVfrRuleNode *pNew;\r
2330\r
2331 if (RuleName == NULL) {\r
2332 return ;\r
2333 }\r
2334\r
2335 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2336 return ;\r
2337 }\r
2338\r
2339 mFreeRuleId++;\r
2340\r
2341 pNew->mNext = mRuleList;\r
2342 mRuleList = pNew;\r
2343}\r
2344\r
2345UINT8\r
2346CVfrRulesDB::GetRuleId (\r
2347 IN CHAR8 *RuleName\r
2348 )\r
2349{\r
2350 SVfrRuleNode *pNode;\r
2351\r
2352 if (RuleName == NULL) {\r
2353 return EFI_RULE_ID_INVALID;\r
2354 }\r
2355\r
2356 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2357 if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2358 return pNode->mRuleId;\r
2359 }\r
2360 }\r
2361\r
2362 return EFI_RULE_ID_INVALID;\r
2363}\r
2364\r
2365CVfrRulesDB gCVfrRulesDB;\r
2366\r
2367EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2368 VOID\r
2369 )\r
2370{\r
2371 mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2372 mInfo.mVarName = EFI_STRING_ID_INVALID;\r
2373 mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2374 mVarType = EFI_IFR_TYPE_OTHER;\r
2375 mVarTotalSize = 0;\r
2376}\r
2377\r
2378EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2379 IN EFI_VARSTORE_INFO &Info\r
2380 )\r
2381{\r
2382 mVarStoreId = Info.mVarStoreId;\r
2383 mInfo.mVarName = Info.mInfo.mVarName;\r
2384 mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2385 mVarType = Info.mVarType;\r
2386 mVarTotalSize = Info.mVarTotalSize;\r
2387}\r
2388\r
2389BOOLEAN\r
2390EFI_VARSTORE_INFO::operator == (\r
2391 IN EFI_VARSTORE_INFO *Info\r
2392 )\r
2393{\r
2394 if ((mVarStoreId == Info->mVarStoreId) &&\r
2395 (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2396 (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2397 (mVarType == Info->mVarType) &&\r
2398 (mVarTotalSize == Info->mVarTotalSize)) {\r
2399 return TRUE;\r
2400 }\r
2401\r
2402 return FALSE;\r
2403}\r
2404\r
74bbe31b
DB
2405BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(\r
2406 IN EFI_VARSTORE_INFO *Info\r
2407 )\r
2408{\r
2409 mVarStoreInfo.mVarType = Info->mVarType;\r
2410 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;\r
2411 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;\r
2412 mVarStoreInfo.mVarStoreId = Info->mVarStoreId;\r
2413 mNext = NULL;\r
2414}\r
2415\r
2416BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()\r
2417{\r
2418 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;\r
2419 mVarStoreInfo.mVarTotalSize = 0;\r
2420 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2421 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
2422 mNext = NULL;\r
2423}\r
2424\r
30fdf114
LG
2425static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2426\r
2427EFI_QUESTION_ID\r
2428CVfrQuestionDB::GetFreeQuestionId (\r
2429 VOID\r
2430 )\r
2431{\r
2432 UINT32 Index, Mask, Offset;\r
2433\r
2434 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2435 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2436 break;\r
2437 }\r
2438 }\r
2439\r
2440 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2441 if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2442 mFreeQIdBitMap[Index] |= Mask;\r
2443 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2444 }\r
2445 }\r
2446\r
2447 return EFI_QUESTION_ID_INVALID;\r
2448}\r
2449\r
2450BOOLEAN\r
2451CVfrQuestionDB::ChekQuestionIdFree (\r
2452 IN EFI_QUESTION_ID QId\r
2453 )\r
2454{\r
2455 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2456 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2457\r
2458 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2459}\r
2460\r
2461VOID\r
2462CVfrQuestionDB::MarkQuestionIdUsed (\r
2463 IN EFI_QUESTION_ID QId\r
2464 )\r
2465{\r
2466 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2467 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2468\r
2469 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2470}\r
2471\r
2472VOID\r
2473CVfrQuestionDB::MarkQuestionIdUnused (\r
2474 IN EFI_QUESTION_ID QId\r
2475 )\r
2476{\r
2477 UINT32 Index = (QId / EFI_BITS_PER_UINT32);\r
2478 UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2479\r
2480 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2481}\r
2482\r
2483SVfrQuestionNode::SVfrQuestionNode (\r
2484 IN CHAR8 *Name,\r
2485 IN CHAR8 *VarIdStr,\r
2486 IN UINT32 BitMask\r
2487 )\r
2488{\r
2489 mName = NULL;\r
2490 mVarIdStr = NULL;\r
2491 mQuestionId = EFI_QUESTION_ID_INVALID;\r
2492 mBitMask = BitMask;\r
2493 mNext = NULL;\r
52302d4d 2494 mQtype = QUESTION_NORMAL;\r
30fdf114
LG
2495\r
2496 if (Name == NULL) {\r
2497 mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2498 strcpy (mName, "$DEFAULT");\r
2499 } else {\r
2500 mName = new CHAR8[strlen (Name) + 1];\r
2501 strcpy (mName, Name);\r
2502 }\r
2503\r
2504 if (VarIdStr != NULL) {\r
2505 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2506 strcpy (mVarIdStr, VarIdStr);\r
2507 } else {\r
2508 mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2509 strcpy (mVarIdStr, "$");\r
2510 }\r
2511}\r
2512\r
2513SVfrQuestionNode::~SVfrQuestionNode (\r
2514 VOID\r
2515 )\r
2516{\r
2517 if (mName != NULL) {\r
2518 delete mName;\r
2519 }\r
2520\r
2521 if (mVarIdStr != NULL) {\r
2522 delete mVarIdStr;\r
2523 }\r
2524}\r
2525\r
2526CVfrQuestionDB::CVfrQuestionDB ()\r
2527{\r
2528 UINT32 Index;\r
2529\r
2530 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2531 mFreeQIdBitMap[Index] = 0;\r
2532 }\r
2533\r
2534 // Question ID 0 is reserved.\r
2535 mFreeQIdBitMap[0] = 0x80000000;\r
2536 mQuestionList = NULL;\r
2537}\r
2538\r
2539CVfrQuestionDB::~CVfrQuestionDB ()\r
2540{\r
2541 SVfrQuestionNode *pNode;\r
2542\r
2543 while (mQuestionList != NULL) {\r
2544 pNode = mQuestionList;\r
2545 mQuestionList = mQuestionList->mNext;\r
2546 delete pNode;\r
2547 }\r
2548}\r
2549\r
2550//\r
2551// Reset to init state\r
2552//\r
2553VOID\r
2554CVfrQuestionDB::ResetInit(\r
2555 IN VOID\r
2556 )\r
2557{\r
2558 UINT32 Index;\r
2559 SVfrQuestionNode *pNode;\r
2560\r
2561 while (mQuestionList != NULL) {\r
2562 pNode = mQuestionList;\r
2563 mQuestionList = mQuestionList->mNext;\r
2564 delete pNode;\r
2565 }\r
2566\r
2567 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2568 mFreeQIdBitMap[Index] = 0;\r
2569 }\r
2570\r
2571 // Question ID 0 is reserved.\r
2572 mFreeQIdBitMap[0] = 0x80000000;\r
2573 mQuestionList = NULL; \r
2574}\r
2575\r
2576VOID\r
2577CVfrQuestionDB::PrintAllQuestion (\r
2578 VOID\r
2579 )\r
2580{\r
2581 SVfrQuestionNode *pNode = NULL;\r
2582\r
2583 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2584 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2585 }\r
2586}\r
2587\r
2588EFI_VFR_RETURN_CODE\r
2589CVfrQuestionDB::RegisterQuestion (\r
2590 IN CHAR8 *Name,\r
2591 IN CHAR8 *VarIdStr,\r
2592 IN OUT EFI_QUESTION_ID &QuestionId\r
2593 )\r
2594{\r
2595 SVfrQuestionNode *pNode = NULL;\r
2596\r
2597 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2598 return VFR_RETURN_REDEFINED;\r
2599 }\r
2600\r
2601 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2602 return VFR_RETURN_OUT_FOR_RESOURCES;\r
2603 }\r
2604\r
2605 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2606 QuestionId = GetFreeQuestionId ();\r
2607 } else {\r
2608 //\r
2609 // For Framework Vfr, don't check question ID conflict.\r
2610 //\r
2611 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2612 delete pNode;\r
2613 return VFR_RETURN_QUESTIONID_REDEFINED;\r
2614 }\r
2615 MarkQuestionIdUsed (QuestionId);\r
2616 }\r
2617 pNode->mQuestionId = QuestionId;\r
2618\r
2619 pNode->mNext = mQuestionList;\r
2620 mQuestionList = pNode;\r
2621\r
2622 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2623\r
2624 return VFR_RETURN_SUCCESS;\r
2625}\r
2626\r
2627VOID\r
2628CVfrQuestionDB::RegisterOldDateQuestion (\r
2629 IN CHAR8 *YearVarId,\r
2630 IN CHAR8 *MonthVarId,\r
2631 IN CHAR8 *DayVarId,\r
2632 IN OUT EFI_QUESTION_ID &QuestionId\r
2633 )\r
2634{\r
2635 SVfrQuestionNode *pNode[3] = {NULL, };\r
2636 UINT32 Index;\r
2637\r
2638 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2639 return;\r
2640 }\r
2641\r
2642 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2643 goto Err;\r
2644 }\r
2645 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2646 goto Err;\r
2647 }\r
2648 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2649 goto Err;\r
2650 }\r
2651\r
2652 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2653 QuestionId = GetFreeQuestionId ();\r
2654 } else {\r
2655 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2656 goto Err;\r
2657 }\r
2658 MarkQuestionIdUsed (QuestionId);\r
2659 }\r
2660\r
2661 pNode[0]->mQuestionId = QuestionId;\r
2662 pNode[1]->mQuestionId = QuestionId;\r
2663 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
2664 pNode[0]->mQtype = QUESTION_DATE;\r
2665 pNode[1]->mQtype = QUESTION_DATE;\r
2666 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
2667 pNode[0]->mNext = pNode[1];\r
2668 pNode[1]->mNext = pNode[2];\r
2669 pNode[2]->mNext = mQuestionList;\r
2670 mQuestionList = pNode[0];\r
2671\r
2672 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2673 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2674 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2675\r
2676 return;\r
2677\r
2678Err:\r
2679 for (Index = 0; Index < 3; Index++) {\r
2680 if (pNode[Index] != NULL) {\r
2681 delete pNode[Index];\r
2682 }\r
2683 }\r
2684 QuestionId = EFI_QUESTION_ID_INVALID;\r
2685}\r
2686\r
2687VOID\r
2688CVfrQuestionDB::RegisterNewDateQuestion (\r
2689 IN CHAR8 *Name,\r
2690 IN CHAR8 *BaseVarId,\r
2691 IN OUT EFI_QUESTION_ID &QuestionId\r
2692 )\r
2693{\r
2694 SVfrQuestionNode *pNode[3] = {NULL, };\r
2695 UINT32 Len;\r
2696 CHAR8 *VarIdStr[3] = {NULL, };\r
2697 CHAR8 Index;\r
2698\r
4afd3d04 2699 if (BaseVarId == NULL && Name == NULL) {\r
e8a47801
LG
2700 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2701 QuestionId = GetFreeQuestionId ();\r
2702 } else {\r
2703 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2704 goto Err;\r
2705 }\r
2706 MarkQuestionIdUsed (QuestionId);\r
2707 }\r
30fdf114
LG
2708 return;\r
2709 }\r
2710\r
4afd3d04
LG
2711 if (BaseVarId != NULL) {\r
2712 Len = strlen (BaseVarId);\r
30fdf114 2713\r
4afd3d04
LG
2714 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2715 if (VarIdStr[0] != NULL) {\r
2716 strcpy (VarIdStr[0], BaseVarId);\r
2717 strcat (VarIdStr[0], ".Year");\r
2718 }\r
2719 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2720 if (VarIdStr[1] != NULL) {\r
2721 strcpy (VarIdStr[1], BaseVarId);\r
2722 strcat (VarIdStr[1], ".Month");\r
2723 }\r
2724 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2725 if (VarIdStr[2] != NULL) {\r
2726 strcpy (VarIdStr[2], BaseVarId);\r
2727 strcat (VarIdStr[2], ".Day");\r
2728 }\r
2729 } else {\r
2730 Len = strlen (Name);\r
2731\r
2732 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2733 if (VarIdStr[0] != NULL) {\r
2734 strcpy (VarIdStr[0], Name);\r
2735 strcat (VarIdStr[0], ".Year");\r
2736 }\r
2737 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2738 if (VarIdStr[1] != NULL) {\r
2739 strcpy (VarIdStr[1], Name);\r
2740 strcat (VarIdStr[1], ".Month");\r
2741 }\r
2742 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2743 if (VarIdStr[2] != NULL) {\r
2744 strcpy (VarIdStr[2], Name);\r
2745 strcat (VarIdStr[2], ".Day");\r
2746 }\r
30fdf114
LG
2747 }\r
2748\r
2749 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
2750 goto Err;\r
2751 }\r
2752 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
2753 goto Err;\r
2754 }\r
2755 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
2756 goto Err;\r
2757 }\r
2758\r
2759 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2760 QuestionId = GetFreeQuestionId ();\r
2761 } else {\r
2762 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2763 goto Err;\r
2764 }\r
2765 MarkQuestionIdUsed (QuestionId);\r
2766 }\r
2767\r
2768 pNode[0]->mQuestionId = QuestionId;\r
2769 pNode[1]->mQuestionId = QuestionId;\r
2770 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
2771 pNode[0]->mQtype = QUESTION_DATE;\r
2772 pNode[1]->mQtype = QUESTION_DATE;\r
2773 pNode[2]->mQtype = QUESTION_DATE;\r
30fdf114
LG
2774 pNode[0]->mNext = pNode[1];\r
2775 pNode[1]->mNext = pNode[2];\r
2776 pNode[2]->mNext = mQuestionList;\r
2777 mQuestionList = pNode[0];\r
2778\r
2779 for (Index = 0; Index < 3; Index++) {\r
2780 if (VarIdStr[Index] != NULL) {\r
2781 delete VarIdStr[Index];\r
2782 }\r
2783 }\r
2784\r
2785 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2786 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2787 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2788\r
2789 return;\r
2790\r
2791Err:\r
2792 for (Index = 0; Index < 3; Index++) {\r
2793 if (pNode[Index] != NULL) {\r
2794 delete pNode[Index];\r
2795 }\r
2796\r
2797 if (VarIdStr[Index] != NULL) {\r
2798 delete VarIdStr[Index];\r
2799 }\r
2800 }\r
2801}\r
2802\r
2803VOID\r
2804CVfrQuestionDB::RegisterOldTimeQuestion (\r
2805 IN CHAR8 *HourVarId,\r
2806 IN CHAR8 *MinuteVarId,\r
2807 IN CHAR8 *SecondVarId,\r
2808 IN OUT EFI_QUESTION_ID &QuestionId\r
2809 )\r
2810{\r
2811 SVfrQuestionNode *pNode[3] = {NULL, };\r
2812 UINT32 Index;\r
2813\r
2814 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
2815 return;\r
2816 }\r
2817\r
2818 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
2819 goto Err;\r
2820 }\r
2821 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
2822 goto Err;\r
2823 }\r
2824 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
2825 goto Err;\r
2826 }\r
2827\r
2828 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2829 QuestionId = GetFreeQuestionId ();\r
2830 } else {\r
2831 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2832 goto Err;\r
2833 }\r
2834 MarkQuestionIdUsed (QuestionId);\r
2835 }\r
2836\r
2837 pNode[0]->mQuestionId = QuestionId;\r
2838 pNode[1]->mQuestionId = QuestionId;\r
2839 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
2840 pNode[0]->mQtype = QUESTION_TIME;\r
2841 pNode[1]->mQtype = QUESTION_TIME;\r
2842 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
2843 pNode[0]->mNext = pNode[1];\r
2844 pNode[1]->mNext = pNode[2];\r
2845 pNode[2]->mNext = mQuestionList;\r
2846 mQuestionList = pNode[0];\r
2847\r
2848 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2849 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2850 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2851\r
2852 return;\r
2853\r
2854Err:\r
2855 for (Index = 0; Index < 3; Index++) {\r
2856 if (pNode[Index] != NULL) {\r
2857 delete pNode[Index];\r
2858 }\r
2859 }\r
2860 QuestionId = EFI_QUESTION_ID_INVALID;\r
2861}\r
2862\r
2863VOID\r
2864CVfrQuestionDB::RegisterNewTimeQuestion (\r
2865 IN CHAR8 *Name,\r
2866 IN CHAR8 *BaseVarId,\r
2867 IN OUT EFI_QUESTION_ID &QuestionId\r
2868 )\r
2869{\r
2870 SVfrQuestionNode *pNode[3] = {NULL, };\r
2871 UINT32 Len;\r
2872 CHAR8 *VarIdStr[3] = {NULL, };\r
2873 CHAR8 Index;\r
2874\r
4afd3d04 2875 if (BaseVarId == NULL && Name == NULL) {\r
e8a47801
LG
2876 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2877 QuestionId = GetFreeQuestionId ();\r
2878 } else {\r
2879 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2880 goto Err;\r
2881 }\r
2882 MarkQuestionIdUsed (QuestionId);\r
2883 }\r
30fdf114
LG
2884 return;\r
2885 }\r
2886\r
4afd3d04
LG
2887 if (BaseVarId != NULL) {\r
2888 Len = strlen (BaseVarId);\r
30fdf114 2889\r
4afd3d04
LG
2890 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2891 if (VarIdStr[0] != NULL) {\r
2892 strcpy (VarIdStr[0], BaseVarId);\r
2893 strcat (VarIdStr[0], ".Hour");\r
2894 }\r
2895 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2896 if (VarIdStr[1] != NULL) {\r
2897 strcpy (VarIdStr[1], BaseVarId);\r
2898 strcat (VarIdStr[1], ".Minute");\r
2899 }\r
2900 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2901 if (VarIdStr[2] != NULL) {\r
2902 strcpy (VarIdStr[2], BaseVarId);\r
2903 strcat (VarIdStr[2], ".Second");\r
2904 }\r
2905 } else {\r
2906 Len = strlen (Name);\r
2907\r
2908 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2909 if (VarIdStr[0] != NULL) {\r
2910 strcpy (VarIdStr[0], Name);\r
2911 strcat (VarIdStr[0], ".Hour");\r
2912 }\r
2913 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2914 if (VarIdStr[1] != NULL) {\r
2915 strcpy (VarIdStr[1], Name);\r
2916 strcat (VarIdStr[1], ".Minute");\r
2917 }\r
2918 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2919 if (VarIdStr[2] != NULL) {\r
2920 strcpy (VarIdStr[2], Name);\r
2921 strcat (VarIdStr[2], ".Second");\r
2922 }\r
30fdf114
LG
2923 }\r
2924\r
2925 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
2926 goto Err;\r
2927 }\r
2928 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
2929 goto Err;\r
2930 }\r
2931 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
2932 goto Err;\r
2933 }\r
2934\r
2935 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2936 QuestionId = GetFreeQuestionId ();\r
2937 } else {\r
2938 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2939 goto Err;\r
2940 }\r
2941 MarkQuestionIdUsed (QuestionId);\r
2942 }\r
2943\r
2944 pNode[0]->mQuestionId = QuestionId;\r
2945 pNode[1]->mQuestionId = QuestionId;\r
2946 pNode[2]->mQuestionId = QuestionId;\r
52302d4d
LG
2947 pNode[0]->mQtype = QUESTION_TIME;\r
2948 pNode[1]->mQtype = QUESTION_TIME;\r
2949 pNode[2]->mQtype = QUESTION_TIME;\r
30fdf114
LG
2950 pNode[0]->mNext = pNode[1];\r
2951 pNode[1]->mNext = pNode[2];\r
2952 pNode[2]->mNext = mQuestionList;\r
2953 mQuestionList = pNode[0];\r
2954\r
2955 for (Index = 0; Index < 3; Index++) {\r
2956 if (VarIdStr[Index] != NULL) {\r
2957 delete VarIdStr[Index];\r
2958 }\r
2959 }\r
2960\r
2961 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2962 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2963 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2964\r
2965 return;\r
2966\r
2967Err:\r
2968 for (Index = 0; Index < 3; Index++) {\r
2969 if (pNode[Index] != NULL) {\r
2970 delete pNode[Index];\r
2971 }\r
2972\r
2973 if (VarIdStr[Index] != NULL) {\r
2974 delete VarIdStr[Index];\r
2975 }\r
2976 }\r
2977}\r
2978\r
4234283c
LG
2979VOID \r
2980CVfrQuestionDB::RegisterRefQuestion (\r
2981 IN CHAR8 *Name,\r
2982 IN CHAR8 *BaseVarId,\r
2983 IN OUT EFI_QUESTION_ID &QuestionId\r
2984 )\r
2985{\r
2986 SVfrQuestionNode *pNode[4] = {NULL, };\r
2987 UINT32 Len;\r
2988 CHAR8 *VarIdStr[4] = {NULL, };\r
2989 CHAR8 Index;\r
2990\r
4afd3d04 2991 if (BaseVarId == NULL && Name == NULL) {\r
4234283c
LG
2992 return;\r
2993 }\r
2994\r
4afd3d04
LG
2995 if (BaseVarId != NULL) {\r
2996 Len = strlen (BaseVarId);\r
4234283c 2997\r
4afd3d04
LG
2998 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
2999 if (VarIdStr[0] != NULL) {\r
3000 strcpy (VarIdStr[0], BaseVarId);\r
3001 strcat (VarIdStr[0], ".QuestionId");\r
3002 }\r
3003 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
3004 if (VarIdStr[1] != NULL) {\r
3005 strcpy (VarIdStr[1], BaseVarId);\r
3006 strcat (VarIdStr[1], ".FormId");\r
3007 }\r
3008 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
3009 if (VarIdStr[2] != NULL) {\r
3010 strcpy (VarIdStr[2], BaseVarId);\r
3011 strcat (VarIdStr[2], ".FormSetGuid");\r
3012 }\r
3013 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
3014 if (VarIdStr[3] != NULL) {\r
3015 strcpy (VarIdStr[3], BaseVarId);\r
3016 strcat (VarIdStr[3], ".DevicePath");\r
3017 }\r
3018 } else {\r
3019 Len = strlen (Name);\r
3020\r
3021 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
3022 if (VarIdStr[0] != NULL) {\r
3023 strcpy (VarIdStr[0], Name);\r
3024 strcat (VarIdStr[0], ".QuestionId");\r
3025 }\r
3026 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
3027 if (VarIdStr[1] != NULL) {\r
3028 strcpy (VarIdStr[1], Name);\r
3029 strcat (VarIdStr[1], ".FormId");\r
3030 }\r
3031 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
3032 if (VarIdStr[2] != NULL) {\r
3033 strcpy (VarIdStr[2], Name);\r
3034 strcat (VarIdStr[2], ".FormSetGuid");\r
3035 }\r
3036 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
3037 if (VarIdStr[3] != NULL) {\r
3038 strcpy (VarIdStr[3], Name);\r
3039 strcat (VarIdStr[3], ".DevicePath");\r
3040 }\r
4234283c
LG
3041 }\r
3042\r
3043 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {\r
3044 goto Err;\r
3045 }\r
3046 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {\r
3047 goto Err;\r
3048 }\r
3049 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {\r
3050 goto Err;\r
3051 }\r
3052 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {\r
3053 goto Err;\r
3054 }\r
3055\r
3056 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3057 QuestionId = GetFreeQuestionId ();\r
3058 } else {\r
3059 if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
3060 goto Err;\r
3061 }\r
3062 MarkQuestionIdUsed (QuestionId);\r
3063 }\r
3064\r
3065 pNode[0]->mQuestionId = QuestionId;\r
3066 pNode[1]->mQuestionId = QuestionId;\r
3067 pNode[2]->mQuestionId = QuestionId;\r
3068 pNode[3]->mQuestionId = QuestionId; \r
3069 pNode[0]->mQtype = QUESTION_REF;\r
3070 pNode[1]->mQtype = QUESTION_REF;\r
3071 pNode[2]->mQtype = QUESTION_REF;\r
3072 pNode[3]->mQtype = QUESTION_REF; \r
3073 pNode[0]->mNext = pNode[1];\r
3074 pNode[1]->mNext = pNode[2];\r
3075 pNode[2]->mNext = pNode[3];\r
3076 pNode[3]->mNext = mQuestionList; \r
3077 mQuestionList = pNode[0];\r
3078\r
3079 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3080 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3081 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3082 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
3083\r
3084 return;\r
3085\r
3086 Err:\r
3087 for (Index = 0; Index < 4; Index++) {\r
3088 if (pNode[Index] != NULL) {\r
3089 delete pNode[Index];\r
3090 }\r
3091\r
3092 if (VarIdStr[Index] != NULL) {\r
3093 delete VarIdStr[Index];\r
3094 }\r
3095 }\r
3096}\r
3097\r
30fdf114
LG
3098EFI_VFR_RETURN_CODE\r
3099CVfrQuestionDB::UpdateQuestionId (\r
3100 IN EFI_QUESTION_ID QId,\r
3101 IN EFI_QUESTION_ID NewQId\r
3102 )\r
3103{\r
3104 SVfrQuestionNode *pNode = NULL;\r
3105 \r
3106 if (QId == NewQId) {\r
3107 // don't update\r
3108 return VFR_RETURN_SUCCESS;\r
3109 }\r
3110 \r
3111 //\r
3112 // For Framework Vfr, don't check question ID conflict.\r
3113 // \r
3114 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
3115 return VFR_RETURN_REDEFINED;\r
3116 }\r
3117\r
3118 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3119 if (pNode->mQuestionId == QId) {\r
3120 break;\r
3121 }\r
3122 }\r
3123\r
3124 if (pNode == NULL) {\r
3125 return VFR_RETURN_UNDEFINED;\r
3126 }\r
3127\r
3128 MarkQuestionIdUnused (QId);\r
3129 pNode->mQuestionId = NewQId;\r
3130 MarkQuestionIdUsed (NewQId);\r
3131\r
3132 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
3133\r
3134 return VFR_RETURN_SUCCESS;\r
3135}\r
3136\r
3137VOID\r
3138CVfrQuestionDB::GetQuestionId (\r
3139 IN CHAR8 *Name,\r
3140 IN CHAR8 *VarIdStr,\r
3141 OUT EFI_QUESTION_ID &QuestionId,\r
52302d4d
LG
3142 OUT UINT32 &BitMask,\r
3143 OUT EFI_QUESION_TYPE *QType\r
30fdf114
LG
3144 )\r
3145{\r
3146 SVfrQuestionNode *pNode;\r
3147\r
3148 QuestionId = EFI_QUESTION_ID_INVALID;\r
3149 BitMask = 0x00000000;\r
52302d4d
LG
3150 if (QType != NULL) {\r
3151 *QType = QUESTION_NORMAL;\r
3152 }\r
30fdf114
LG
3153\r
3154 if ((Name == NULL) && (VarIdStr == NULL)) {\r
3155 return ;\r
3156 }\r
3157\r
3158 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3159 if (Name != NULL) {\r
3160 if (strcmp (pNode->mName, Name) != 0) {\r
3161 continue;\r
3162 }\r
3163 }\r
3164\r
3165 if (VarIdStr != NULL) {\r
3166 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
3167 continue;\r
3168 }\r
3169 }\r
3170\r
3171 QuestionId = pNode->mQuestionId;\r
3172 BitMask = pNode->mBitMask;\r
52302d4d
LG
3173 if (QType != NULL) {\r
3174 *QType = pNode->mQtype;\r
3175 }\r
30fdf114
LG
3176 break;\r
3177 }\r
3178\r
3179 return ;\r
3180}\r
3181\r
3182EFI_VFR_RETURN_CODE\r
3183CVfrQuestionDB::FindQuestion (\r
3184 IN EFI_QUESTION_ID QuestionId\r
3185 )\r
3186{\r
3187 SVfrQuestionNode *pNode;\r
3188\r
3189 if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
3190 return VFR_RETURN_INVALID_PARAMETER;\r
3191 }\r
3192\r
3193 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3194 if (pNode->mQuestionId == QuestionId) {\r
3195 return VFR_RETURN_SUCCESS;\r
3196 }\r
3197 }\r
3198\r
3199 return VFR_RETURN_UNDEFINED;\r
3200}\r
3201\r
3202EFI_VFR_RETURN_CODE\r
3203CVfrQuestionDB::FindQuestion (\r
3204 IN CHAR8 *Name\r
3205 )\r
3206{\r
3207 SVfrQuestionNode *pNode;\r
3208\r
3209 if (Name == NULL) {\r
3210 return VFR_RETURN_FATAL_ERROR;\r
3211 }\r
3212\r
3213 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
3214 if (strcmp (pNode->mName, Name) == 0) {\r
3215 return VFR_RETURN_SUCCESS;\r
3216 }\r
3217 }\r
3218\r
3219 return VFR_RETURN_UNDEFINED;\r
3220}\r
3221\r
4234283c
LG
3222CVfrStringDB::CVfrStringDB ()\r
3223{\r
3224 mStringFileName = NULL;\r
3225}\r
3226\r
3227CVfrStringDB::~CVfrStringDB ()\r
3228{\r
3229 if (mStringFileName != NULL) {\r
3230 delete mStringFileName;\r
3231 }\r
3232 mStringFileName = NULL;\r
3233}\r
3234\r
3235\r
3236VOID \r
3237CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
3238{\r
3239 UINT32 FileLen = 0;\r
3240\r
3241 if (StringFileName == NULL) {\r
3242 return;\r
3243 }\r
3244\r
3245 FileLen = strlen (StringFileName) + 1;\r
3246 mStringFileName = new CHAR8[FileLen];\r
3247 if (mStringFileName == NULL) {\r
3248 return;\r
3249 }\r
3250\r
3251 strcpy (mStringFileName, StringFileName);\r
3252 mStringFileName[FileLen - 1] = '\0';\r
3253}\r
3254\r
64b2609f
LG
3255\r
3256/**\r
3257 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language \r
3258 from a set of supported languages.\r
3259\r
3260 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that\r
3261 contains a set of language codes.\r
3262 @param[in] Language A variable that contains pointers to Null-terminated\r
3263 ASCII strings that contain one language codes.\r
3264\r
3265 @retval FALSE The best matching language could not be found in SupportedLanguages.\r
3266 @retval TRUE The best matching language could be found in SupportedLanguages.\r
3267\r
3268**/\r
3269BOOLEAN\r
3270CVfrStringDB::GetBestLanguage (\r
3271 IN CONST CHAR8 *SupportedLanguages,\r
3272 IN CHAR8 *Language\r
3273 )\r
3274{\r
3275 UINTN CompareLength;\r
3276 UINTN LanguageLength;\r
3277 CONST CHAR8 *Supported;\r
3278\r
3279 if (SupportedLanguages == NULL || Language == NULL){\r
3280 return FALSE;\r
3281 }\r
3282\r
3283 //\r
3284 // Determine the length of the first RFC 4646 language code in Language\r
3285 //\r
3286 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
3287\r
3288 //\r
3289 // Trim back the length of Language used until it is empty\r
3290 //\r
3291 while (LanguageLength > 0) {\r
3292 //\r
3293 // Loop through all language codes in SupportedLanguages\r
3294 //\r
3295 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
3296 //\r
3297 // Skip ';' characters in Supported\r
3298 //\r
3299 for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
3300 //\r
3301 // Determine the length of the next language code in Supported\r
3302 //\r
3303 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
3304 //\r
3305 // If Language is longer than the Supported, then skip to the next language\r
3306 //\r
3307 if (LanguageLength > CompareLength) {\r
3308 continue;\r
3309 }\r
3310\r
3311 //\r
3312 // See if the first LanguageLength characters in Supported match Language\r
3313 //\r
3314 if (strncmp (Supported, Language, LanguageLength) == 0) {\r
3315 return TRUE;\r
3316 }\r
3317 }\r
3318\r
3319 //\r
3320 // Trim Language from the right to the next '-' character \r
3321 //\r
3322 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
3323 }\r
3324\r
3325 //\r
3326 // No matches were found \r
3327 //\r
3328 return FALSE;\r
3329}\r
3330\r
3331\r
4234283c
LG
3332CHAR8 *\r
3333CVfrStringDB::GetVarStoreNameFormStringId (\r
3334 IN EFI_STRING_ID StringId\r
3335 )\r
3336{\r
3337 FILE *pInFile = NULL;\r
3338 UINT32 NameOffset;\r
3339 UINT32 Length;\r
3340 UINT8 *StringPtr;\r
3341 CHAR8 *StringName;\r
3342 CHAR16 *UnicodeString;\r
3343 CHAR8 *VarStoreName = NULL;\r
3344 CHAR8 *DestTmp;\r
3345 UINT8 *Current;\r
3346 EFI_STATUS Status;\r
3347 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];\r
3348 UINT8 BlockType;\r
3349 EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
3350 \r
3351 if (mStringFileName == '\0' ) {\r
3352 return NULL;\r
3353 }\r
3354\r
1be2ed90 3355 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {\r
4234283c
LG
3356 return NULL;\r
3357 }\r
3358\r
3359 //\r
3360 // Get file length.\r
3361 //\r
3362 fseek (pInFile, 0, SEEK_END);\r
3363 Length = ftell (pInFile);\r
3364 fseek (pInFile, 0, SEEK_SET);\r
3365\r
3366 //\r
3367 // Get file data.\r
3368 //\r
3369 StringPtr = new UINT8[Length];\r
3370 if (StringPtr == NULL) {\r
3371 fclose (pInFile);\r
3372 return NULL;\r
3373 }\r
3374 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
3375 fclose (pInFile);\r
3376\r
3377 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
3378 //\r
3379 // Check the String package.\r
3380 //\r
3381 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
3382 delete StringPtr;\r
3383 return NULL;\r
3384 }\r
3385\r
3386 //\r
64b2609f 3387 // Search the language, get best language base on RFC 4647 matching algorithm.\r
4234283c
LG
3388 //\r
3389 Current = StringPtr;\r
64b2609f 3390 while (!GetBestLanguage ("en", PkgHeader->Language)) {\r
4234283c
LG
3391 Current += PkgHeader->Header.Length;\r
3392 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
3393 //\r
64b2609f 3394 // If can't find string package base on language, just return the first string package.\r
4234283c
LG
3395 //\r
3396 if (Current - StringPtr >= Length) {\r
3397 Current = StringPtr;\r
64b2609f 3398 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
4234283c
LG
3399 break;\r
3400 }\r
3401 }\r
3402\r
3403 Current += PkgHeader->HdrSize;\r
3404 //\r
3405 // Find the string block according the stringId.\r
3406 //\r
3407 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
3408 if (Status != EFI_SUCCESS) {\r
3409 delete StringPtr;\r
3410 return NULL;\r
3411 }\r
3412\r
3413 //\r
3414 // Get varstore name according the string type.\r
3415 //\r
3416 switch (BlockType) {\r
3417 case EFI_HII_SIBT_STRING_SCSU:\r
3418 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3419 case EFI_HII_SIBT_STRINGS_SCSU:\r
3420 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3421 StringName = (CHAR8*)(Current + NameOffset);\r
3422 VarStoreName = new CHAR8[strlen(StringName) + 1];\r
3423 strcpy (VarStoreName, StringName);\r
3424 break;\r
3425 case EFI_HII_SIBT_STRING_UCS2:\r
3426 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3427 case EFI_HII_SIBT_STRINGS_UCS2:\r
3428 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3429 UnicodeString = (CHAR16*)(Current + NameOffset);\r
3430 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
3431 DestTmp = new CHAR8[Length / 2 + 1];\r
3432 VarStoreName = DestTmp;\r
3433 while (*UnicodeString != '\0') {\r
3434 *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
3435 }\r
3436 *DestTmp = '\0';\r
3437 break;\r
3438 default:\r
3439 break;\r
3440 }\r
3441\r
3442 delete StringPtr;\r
3443\r
3444 return VarStoreName;\r
3445}\r
3446\r
3447EFI_STATUS\r
3448CVfrStringDB::FindStringBlock (\r
3449 IN UINT8 *StringData,\r
3450 IN EFI_STRING_ID StringId,\r
3451 OUT UINT32 *StringTextOffset,\r
3452 OUT UINT8 *BlockType\r
3453 )\r
3454{\r
3455 UINT8 *BlockHdr;\r
3456 EFI_STRING_ID CurrentStringId;\r
3457 UINT32 BlockSize;\r
3458 UINT32 Index;\r
3459 UINT8 *StringTextPtr;\r
3460 UINT32 Offset;\r
3461 UINT16 StringCount;\r
3462 UINT16 SkipCount;\r
3463 UINT8 Length8;\r
3464 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
3465 UINT32 Length32;\r
3466 UINT32 StringSize;\r
3467\r
3468 CurrentStringId = 1;\r
3469\r
3470 //\r
3471 // Parse the string blocks to get the string text and font.\r
3472 //\r
3473 BlockHdr = StringData;\r
3474 BlockSize = 0;\r
3475 Offset = 0;\r
3476 while (*BlockHdr != EFI_HII_SIBT_END) {\r
3477 switch (*BlockHdr) {\r
3478 case EFI_HII_SIBT_STRING_SCSU:\r
3479 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3480 StringTextPtr = BlockHdr + Offset;\r
3481 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3482 CurrentStringId++;\r
3483 break;\r
3484\r
3485 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
3486 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3487 StringTextPtr = BlockHdr + Offset;\r
3488 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3489 CurrentStringId++;\r
3490 break;\r
3491\r
3492 case EFI_HII_SIBT_STRINGS_SCSU:\r
3493 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3494 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
3495 BlockSize += StringTextPtr - BlockHdr;\r
3496\r
3497 for (Index = 0; Index < StringCount; Index++) {\r
3498 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3499 if (CurrentStringId == StringId) {\r
3500 *BlockType = *BlockHdr;\r
3501 *StringTextOffset = StringTextPtr - StringData;\r
3502 return EFI_SUCCESS;\r
3503 }\r
3504 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3505 CurrentStringId++;\r
3506 }\r
3507 break;\r
3508\r
3509 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
3510 memcpy (\r
3511 &StringCount,\r
3512 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3513 sizeof (UINT16)\r
3514 );\r
3515 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
3516 BlockSize += StringTextPtr - BlockHdr;\r
3517\r
3518 for (Index = 0; Index < StringCount; Index++) {\r
3519 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
3520 if (CurrentStringId == StringId) {\r
3521 *BlockType = *BlockHdr;\r
3522 *StringTextOffset = StringTextPtr - StringData;\r
3523 return EFI_SUCCESS;\r
3524 }\r
3525 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
3526 CurrentStringId++;\r
3527 }\r
3528 break;\r
3529\r
3530 case EFI_HII_SIBT_STRING_UCS2:\r
3531 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
3532 StringTextPtr = BlockHdr + Offset;\r
3533 //\r
3534 // Use StringSize to store the size of the specified string, including the NULL\r
3535 // terminator.\r
3536 //\r
3537 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3538 BlockSize += Offset + StringSize;\r
3539 CurrentStringId++;\r
3540 break;\r
3541\r
3542 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
3543 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3544 StringTextPtr = BlockHdr + Offset;\r
3545 //\r
3546 // Use StrSize to store the size of the specified string, including the NULL\r
3547 // terminator.\r
3548 //\r
3549 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3550 BlockSize += Offset + StringSize;\r
3551 CurrentStringId++;\r
3552 break;\r
3553\r
3554 case EFI_HII_SIBT_STRINGS_UCS2:\r
3555 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
3556 StringTextPtr = BlockHdr + Offset;\r
3557 BlockSize += Offset;\r
3558 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3559 for (Index = 0; Index < StringCount; Index++) {\r
3560 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3561 BlockSize += StringSize;\r
3562 if (CurrentStringId == StringId) {\r
3563 *BlockType = *BlockHdr;\r
3564 *StringTextOffset = StringTextPtr - StringData;\r
3565 return EFI_SUCCESS;\r
3566 }\r
3567 StringTextPtr = StringTextPtr + StringSize;\r
3568 CurrentStringId++;\r
3569 }\r
3570 break;\r
3571\r
3572 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
3573 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
3574 StringTextPtr = BlockHdr + Offset;\r
3575 BlockSize += Offset;\r
3576 memcpy (\r
3577 &StringCount,\r
3578 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3579 sizeof (UINT16)\r
3580 );\r
3581 for (Index = 0; Index < StringCount; Index++) {\r
3582 StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
3583 BlockSize += StringSize;\r
3584 if (CurrentStringId == StringId) {\r
3585 *BlockType = *BlockHdr;\r
3586 *StringTextOffset = StringTextPtr - StringData;\r
3587 return EFI_SUCCESS;\r
3588 }\r
3589 StringTextPtr = StringTextPtr + StringSize;\r
3590 CurrentStringId++;\r
3591 }\r
3592 break;\r
3593\r
3594 case EFI_HII_SIBT_DUPLICATE:\r
3595 if (CurrentStringId == StringId) {\r
3596 //\r
3597 // Incoming StringId is an id of a duplicate string block.\r
3598 // Update the StringId to be the previous string block.\r
3599 // Go back to the header of string block to search.\r
3600 //\r
3601 memcpy (\r
3602 &StringId,\r
3603 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
3604 sizeof (EFI_STRING_ID)\r
3605 );\r
3606 CurrentStringId = 1;\r
3607 BlockSize = 0;\r
3608 } else {\r
3609 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
3610 CurrentStringId++;\r
3611 }\r
3612 break;\r
3613\r
3614 case EFI_HII_SIBT_SKIP1:\r
3615 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
3616 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3617 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
3618 break;\r
3619\r
3620 case EFI_HII_SIBT_SKIP2:\r
3621 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
3622 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
3623 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
3624 break;\r
3625\r
3626 case EFI_HII_SIBT_EXT1:\r
3627 memcpy (\r
3628 &Length8,\r
3629 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3630 sizeof (UINT8)\r
3631 );\r
3632 BlockSize += Length8;\r
3633 break;\r
3634\r
3635 case EFI_HII_SIBT_EXT2:\r
3636 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
3637 BlockSize += Ext2.Length;\r
3638 break;\r
3639\r
3640 case EFI_HII_SIBT_EXT4:\r
3641 memcpy (\r
3642 &Length32,\r
3643 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
3644 sizeof (UINT32)\r
3645 );\r
3646\r
3647 BlockSize += Length32;\r
3648 break;\r
3649\r
3650 default:\r
3651 break;\r
3652 }\r
3653\r
3654 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
3655 *StringTextOffset = BlockHdr - StringData + Offset;\r
3656 *BlockType = *BlockHdr;\r
3657\r
3658 if (StringId == CurrentStringId - 1) {\r
3659 //\r
3660 // if only one skip item, return EFI_NOT_FOUND.\r
3661 //\r
3662 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
3663 return EFI_NOT_FOUND;\r
3664 } else {\r
3665 return EFI_SUCCESS;\r
3666 }\r
3667 }\r
3668\r
3669 if (StringId < CurrentStringId - 1) {\r
3670 return EFI_NOT_FOUND;\r
3671 }\r
3672 }\r
3673 BlockHdr = StringData + BlockSize;\r
3674 }\r
3675\r
3676 return EFI_NOT_FOUND;\r
3677}\r
3678\r
3679UINT32\r
3680CVfrStringDB::GetUnicodeStringTextSize (\r
3681 IN UINT8 *StringSrc\r
3682 )\r
3683{\r
3684 UINT32 StringSize;\r
3685 CHAR16 *StringPtr;\r
3686\r
3687 StringSize = sizeof (CHAR16);\r
3688 StringPtr = (UINT16*)StringSrc;\r
3689 while (*StringPtr++ != L'\0') {\r
3690 StringSize += sizeof (CHAR16);\r
3691 }\r
3692\r
3693 return StringSize;\r
3694}\r
3695\r
30fdf114
LG
3696BOOLEAN VfrCompatibleMode = FALSE;\r
3697\r
3698CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
74bbe31b
DB
3699CVfrDefaultStore gCVfrDefaultStore;\r
3700CVfrDataStorage gCVfrDataStorage;\r
30fdf114 3701\r
52302d4d 3702\r