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