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