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