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