]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
CommitLineData
30fdf114 1/** @file\r
f7496d71 2\r
30fdf114
LG
3 The definition of CFormPkg's member function\r
4\r
f7496d71 5Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
30fdf114
LG
7\r
8**/\r
9\r
10#include "stdio.h"\r
9b78c54a 11#include "assert.h"\r
30fdf114
LG
12#include "VfrFormPkg.h"\r
13\r
14/*\r
15 * The definition of CFormPkg's member function\r
16 */\r
17\r
18SPendingAssign::SPendingAssign (\r
f7496d71
LG
19 IN CHAR8 *Key,\r
20 IN VOID *Addr,\r
21 IN UINT32 Len,\r
30fdf114 22 IN UINT32 LineNo,\r
52302d4d 23 IN CONST CHAR8 *Msg\r
30fdf114
LG
24 )\r
25{\r
26 mKey = NULL;\r
27 mAddr = Addr;\r
28 mLen = Len;\r
29 mFlag = PENDING;\r
30 mLineNo = LineNo;\r
31 mMsg = NULL;\r
32 mNext = NULL;\r
33 if (Key != NULL) {\r
34 mKey = new CHAR8[strlen (Key) + 1];\r
35 if (mKey != NULL) {\r
36 strcpy (mKey, Key);\r
37 }\r
38 }\r
39\r
40 if (Msg != NULL) {\r
41 mMsg = new CHAR8[strlen (Msg) + 1];\r
42 if (mMsg != NULL) {\r
43 strcpy (mMsg, Msg);\r
44 }\r
45 }\r
46}\r
47\r
48SPendingAssign::~SPendingAssign (\r
49 VOID\r
50 )\r
51{\r
52 if (mKey != NULL) {\r
fd542523 53 delete[] mKey;\r
30fdf114
LG
54 }\r
55 mAddr = NULL;\r
56 mLen = 0;\r
57 mLineNo = 0;\r
58 if (mMsg != NULL) {\r
fd542523 59 delete[] mMsg;\r
30fdf114
LG
60 }\r
61 mNext = NULL;\r
62}\r
63\r
64VOID\r
65SPendingAssign::SetAddrAndLen (\r
f7496d71 66 IN VOID *Addr,\r
30fdf114
LG
67 IN UINT32 LineNo\r
68 )\r
69{\r
70 mAddr = Addr;\r
71 mLineNo = LineNo;\r
72}\r
73\r
74VOID\r
75SPendingAssign::AssignValue (\r
f7496d71 76 IN VOID *Addr,\r
30fdf114
LG
77 IN UINT32 Len\r
78 )\r
79{\r
f51461c8 80 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));\r
30fdf114
LG
81 mFlag = ASSIGNED;\r
82}\r
83\r
84CHAR8 *\r
85SPendingAssign::GetKey (\r
86 VOID\r
87 )\r
88{\r
89 return mKey;\r
90}\r
91\r
92CFormPkg::CFormPkg (\r
ed395cfe 93 IN UINT32 BufferSize\r
30fdf114
LG
94 )\r
95{\r
96 CHAR8 *BufferStart;\r
97 CHAR8 *BufferEnd;\r
98 SBufferNode *Node;\r
99\r
100 mPkgLength = 0;\r
b748e35c 101 mBufferSize = 0;\r
30fdf114 102 mBufferNodeQueueHead = NULL;\r
b748e35c 103 mBufferNodeQueueTail = NULL;\r
30fdf114 104 mCurrBufferNode = NULL;\r
b748e35c
HW
105 mReadBufferNode = NULL;\r
106 mReadBufferOffset = 0;\r
107 PendingAssignList = NULL;\r
30fdf114
LG
108\r
109 Node = new SBufferNode;\r
110 if (Node == NULL) {\r
111 return ;\r
112 }\r
113 BufferStart = new CHAR8[BufferSize];\r
114 if (BufferStart == NULL) {\r
bdf5f731 115 delete Node;\r
30fdf114
LG
116 return;\r
117 }\r
118 BufferEnd = BufferStart + BufferSize;\r
119\r
120 memset (BufferStart, 0, BufferSize);\r
121 Node->mBufferStart = BufferStart;\r
122 Node->mBufferEnd = BufferEnd;\r
123 Node->mBufferFree = BufferStart;\r
124 Node->mNext = NULL;\r
125\r
126 mBufferSize = BufferSize;\r
127 mBufferNodeQueueHead = Node;\r
128 mBufferNodeQueueTail = Node;\r
129 mCurrBufferNode = Node;\r
130}\r
131\r
132CFormPkg::~CFormPkg ()\r
133{\r
134 SBufferNode *pBNode;\r
135 SPendingAssign *pPNode;\r
136\r
137 while (mBufferNodeQueueHead != NULL) {\r
138 pBNode = mBufferNodeQueueHead;\r
139 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
140 if (pBNode->mBufferStart != NULL) {\r
f7e98581 141 delete[] pBNode->mBufferStart;\r
30fdf114
LG
142 delete pBNode;\r
143 }\r
144 }\r
145 mBufferNodeQueueTail = NULL;\r
146 mCurrBufferNode = NULL;\r
147\r
148 while (PendingAssignList != NULL) {\r
149 pPNode = PendingAssignList;\r
150 PendingAssignList = PendingAssignList->mNext;\r
151 delete pPNode;\r
152 }\r
153 PendingAssignList = NULL;\r
154}\r
155\r
4afd3d04
LG
156SBufferNode *\r
157CFormPkg::CreateNewNode (\r
158 VOID\r
159 )\r
160{\r
161 SBufferNode *Node;\r
162\r
163 Node = new SBufferNode;\r
164 if (Node == NULL) {\r
165 return NULL;\r
166 }\r
167\r
168 Node->mBufferStart = new CHAR8[mBufferSize];\r
169 if (Node->mBufferStart == NULL) {\r
170 delete Node;\r
171 return NULL;\r
172 } else {\r
173 memset (Node->mBufferStart, 0, mBufferSize);\r
174 Node->mBufferEnd = Node->mBufferStart + mBufferSize;\r
175 Node->mBufferFree = Node->mBufferStart;\r
176 Node->mNext = NULL;\r
177 }\r
178\r
179 return Node;\r
180}\r
181\r
30fdf114
LG
182CHAR8 *\r
183CFormPkg::IfrBinBufferGet (\r
184 IN UINT32 Len\r
185 )\r
186{\r
4afd3d04
LG
187 CHAR8 *BinBuffer = NULL;\r
188 SBufferNode *Node = NULL;\r
30fdf114
LG
189\r
190 if ((Len == 0) || (Len > mBufferSize)) {\r
191 return NULL;\r
192 }\r
193\r
194 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
195 BinBuffer = mCurrBufferNode->mBufferFree;\r
196 mCurrBufferNode->mBufferFree += Len;\r
197 } else {\r
4afd3d04 198 Node = CreateNewNode ();\r
30fdf114
LG
199 if (Node == NULL) {\r
200 return NULL;\r
201 }\r
202\r
30fdf114
LG
203 if (mBufferNodeQueueTail == NULL) {\r
204 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
205 } else {\r
206 mBufferNodeQueueTail->mNext = Node;\r
207 mBufferNodeQueueTail = Node;\r
208 }\r
209 mCurrBufferNode = Node;\r
210\r
211 //\r
212 // Now try again.\r
213 //\r
214 BinBuffer = mCurrBufferNode->mBufferFree;\r
215 mCurrBufferNode->mBufferFree += Len;\r
216 }\r
217\r
218 mPkgLength += Len;\r
219\r
220 return BinBuffer;\r
221}\r
222\r
223inline\r
224UINT32\r
225CFormPkg::GetPkgLength (\r
226 VOID\r
227 )\r
228{\r
229 return mPkgLength;\r
230}\r
231\r
232VOID\r
233CFormPkg::Open (\r
234 VOID\r
235 )\r
236{\r
237 mReadBufferNode = mBufferNodeQueueHead;\r
238 mReadBufferOffset = 0;\r
239}\r
240\r
241VOID\r
242CFormPkg::Close (\r
243 VOID\r
244 )\r
245{\r
246 mReadBufferNode = NULL;\r
247 mReadBufferOffset = 0;\r
248}\r
249\r
250UINT32\r
251CFormPkg::Read (\r
f7496d71 252 IN CHAR8 *Buffer,\r
30fdf114
LG
253 IN UINT32 Size\r
254 )\r
255{\r
256 UINT32 Index;\r
257\r
258 if ((Size == 0) || (Buffer == NULL)) {\r
259 return 0;\r
260 }\r
261\r
262 if (mReadBufferNode == NULL) {\r
4afd3d04 263 return 0;\r
30fdf114
LG
264 }\r
265\r
266 for (Index = 0; Index < Size; Index++) {\r
267 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
268 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
269 } else {\r
270 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
271 return Index;\r
272 } else {\r
273 mReadBufferOffset = 0;\r
4afd3d04 274 Index --;\r
30fdf114
LG
275 }\r
276 }\r
277 }\r
278\r
279 return Size;\r
280}\r
281\r
282EFI_VFR_RETURN_CODE\r
283CFormPkg::BuildPkgHdr (\r
284 OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
285 )\r
286{\r
287 if (PkgHdr == NULL) {\r
288 return VFR_RETURN_FATAL_ERROR;\r
289 }\r
290\r
291 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
292 return VFR_RETURN_OUT_FOR_RESOURCES;\r
293 }\r
294\r
295 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
296 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
297\r
298 return VFR_RETURN_SUCCESS;\r
299}\r
300\r
301EFI_VFR_RETURN_CODE\r
302CFormPkg::BuildPkg (\r
303 OUT PACKAGE_DATA &TBuffer\r
304 )\r
305{\r
f7496d71 306\r
30fdf114
LG
307 CHAR8 *Temp;\r
308 UINT32 Size;\r
309 CHAR8 Buffer[1024];\r
310\r
311 if (TBuffer.Buffer != NULL) {\r
312 delete TBuffer.Buffer;\r
313 }\r
314\r
315 TBuffer.Size = mPkgLength;\r
316 TBuffer.Buffer = NULL;\r
317 if (TBuffer.Size != 0) {\r
318 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
319 } else {\r
320 return VFR_RETURN_SUCCESS;\r
321 }\r
322\r
323 Temp = TBuffer.Buffer;\r
324 Open ();\r
325 while ((Size = Read (Buffer, 1024)) != 0) {\r
326 memcpy (Temp, Buffer, Size);\r
327 Temp += Size;\r
328 }\r
329 Close ();\r
330 return VFR_RETURN_SUCCESS;\r
331}\r
332\r
333\r
334EFI_VFR_RETURN_CODE\r
335CFormPkg::BuildPkg (\r
336 IN FILE *Output,\r
337 IN PACKAGE_DATA *PkgData\r
338 )\r
339{\r
340 EFI_VFR_RETURN_CODE Ret;\r
341 CHAR8 Buffer[1024];\r
342 UINT32 Size;\r
343 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
344\r
345 if (Output == NULL) {\r
346 return VFR_RETURN_FATAL_ERROR;\r
347 }\r
348\r
349 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
350 return Ret;\r
351 }\r
352 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
353 delete PkgHdr;\r
f7496d71 354\r
30fdf114
LG
355 if (PkgData == NULL) {\r
356 Open ();\r
357 while ((Size = Read (Buffer, 1024)) != 0) {\r
358 fwrite (Buffer, Size, 1, Output);\r
359 }\r
360 Close ();\r
361 } else {\r
362 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);\r
363 }\r
364\r
365 return VFR_RETURN_SUCCESS;\r
366}\r
367\r
368VOID\r
369CFormPkg::_WRITE_PKG_LINE (\r
52302d4d
LG
370 IN FILE *pFile,\r
371 IN UINT32 LineBytes,\r
372 IN CONST CHAR8 *LineHeader,\r
373 IN CHAR8 *BlkBuf,\r
374 IN UINT32 BlkSize\r
30fdf114
LG
375 )\r
376{\r
377 UINT32 Index;\r
378\r
379 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
380 return;\r
381 }\r
382\r
383 for (Index = 0; Index < BlkSize; Index++) {\r
384 if ((Index % LineBytes) == 0) {\r
385 fprintf (pFile, "\n%s", LineHeader);\r
386 }\r
387 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
388 }\r
389}\r
390\r
391VOID\r
392CFormPkg::_WRITE_PKG_END (\r
52302d4d
LG
393 IN FILE *pFile,\r
394 IN UINT32 LineBytes,\r
395 IN CONST CHAR8 *LineHeader,\r
396 IN CHAR8 *BlkBuf,\r
397 IN UINT32 BlkSize\r
30fdf114
LG
398 )\r
399{\r
400 UINT32 Index;\r
401\r
402 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
403 return;\r
404 }\r
405\r
406 for (Index = 0; Index < BlkSize - 1; Index++) {\r
407 if ((Index % LineBytes) == 0) {\r
408 fprintf (pFile, "\n%s", LineHeader);\r
409 }\r
410 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
411 }\r
412\r
413 if ((Index % LineBytes) == 0) {\r
414 fprintf (pFile, "\n%s", LineHeader);\r
415 }\r
416 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
417}\r
418\r
419#define BYTES_PRE_LINE 0x10\r
4afd3d04
LG
420UINT32 gAdjustOpcodeOffset = 0;\r
421BOOLEAN gNeedAdjustOpcode = FALSE;\r
422UINT32 gAdjustOpcodeLen = 0;\r
30fdf114 423\r
f7496d71 424EFI_VFR_RETURN_CODE\r
30fdf114
LG
425CFormPkg::GenCFile (\r
426 IN CHAR8 *BaseName,\r
427 IN FILE *pFile,\r
428 IN PACKAGE_DATA *PkgData\r
429 )\r
430{\r
431 EFI_VFR_RETURN_CODE Ret;\r
432 CHAR8 Buffer[BYTES_PRE_LINE * 8];\r
433 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
434 UINT32 PkgLength = 0;\r
435 UINT32 ReadSize = 0;\r
436\r
437 if ((BaseName == NULL) || (pFile == NULL)) {\r
438 return VFR_RETURN_FATAL_ERROR;\r
439 }\r
440\r
441 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
442\r
443 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
444 return Ret;\r
445 }\r
446\r
447 //\r
448 // For framework vfr file, the extension framework header will be added.\r
449 //\r
450 if (VfrCompatibleMode) {\r
f7496d71
LG
451 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
452 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
453 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));\r
454 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
455 PkgLength = 3;\r
456 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16));\r
457 } else {\r
458 fprintf (pFile, " // ARRAY LENGTH\n");\r
459 PkgLength = PkgHdr->Length + sizeof (UINT32);\r
460 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));\r
461 }\r
30fdf114
LG
462\r
463 fprintf (pFile, "\n\n // PACKAGE HEADER\n");\r
464 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
465 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
466\r
467 fprintf (pFile, "\n\n // PACKAGE DATA\n");\r
f7496d71 468\r
30fdf114
LG
469 if (PkgData == NULL) {\r
470 Open ();\r
471 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
472 PkgLength += ReadSize;\r
473 if (PkgLength < PkgHdr->Length) {\r
474 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
475 } else {\r
476 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
477 }\r
478 }\r
479 Close ();\r
480 } else {\r
481 if (PkgData->Size % BYTES_PRE_LINE != 0) {\r
482 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);\r
483 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
484 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);\r
485 } else {\r
486 PkgLength = PkgData->Size - BYTES_PRE_LINE;\r
487 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
488 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);\r
489 }\r
490 }\r
491\r
492 delete PkgHdr;\r
493 fprintf (pFile, "\n};\n");\r
494\r
495 return VFR_RETURN_SUCCESS;\r
496}\r
497\r
498EFI_VFR_RETURN_CODE\r
499CFormPkg::AssignPending (\r
f7496d71
LG
500 IN CHAR8 *Key,\r
501 IN VOID *ValAddr,\r
30fdf114
LG
502 IN UINT32 ValLen,\r
503 IN UINT32 LineNo,\r
52302d4d 504 IN CONST CHAR8 *Msg\r
30fdf114
LG
505 )\r
506{\r
507 SPendingAssign *pNew;\r
508\r
509 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);\r
510 if (pNew == NULL) {\r
511 return VFR_RETURN_OUT_FOR_RESOURCES;\r
512 }\r
513\r
514 pNew->mNext = PendingAssignList;\r
515 PendingAssignList = pNew;\r
516 return VFR_RETURN_SUCCESS;\r
517}\r
518\r
519VOID\r
520CFormPkg::DoPendingAssign (\r
f7496d71
LG
521 IN CHAR8 *Key,\r
522 IN VOID *ValAddr,\r
30fdf114
LG
523 IN UINT32 ValLen\r
524 )\r
525{\r
526 SPendingAssign *pNode;\r
527\r
528 if ((Key == NULL) || (ValAddr == NULL)) {\r
529 return;\r
530 }\r
531\r
532 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
533 if (strcmp (pNode->mKey, Key) == 0) {\r
534 pNode->AssignValue (ValAddr, ValLen);\r
535 }\r
536 }\r
537}\r
538\r
539bool\r
540CFormPkg::HavePendingUnassigned (\r
541 VOID\r
542 )\r
543{\r
544 SPendingAssign *pNode;\r
545\r
546 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
547 if (pNode->mFlag == PENDING) {\r
548 return TRUE;\r
549 }\r
550 }\r
551\r
552 return FALSE;\r
553}\r
554\r
555VOID\r
556CFormPkg::PendingAssignPrintAll (\r
557 VOID\r
558 )\r
559{\r
560 SPendingAssign *pNode;\r
561\r
562 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
563 if (pNode->mFlag == PENDING) {\r
564 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);\r
565 }\r
566 }\r
567}\r
568\r
4afd3d04
LG
569SBufferNode *\r
570CFormPkg::GetBinBufferNodeForAddr (\r
571 IN CHAR8 *BinBuffAddr\r
572 )\r
573{\r
574 SBufferNode *TmpNode;\r
575\r
576 TmpNode = mBufferNodeQueueHead;\r
577\r
578 while (TmpNode != NULL) {\r
579 if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {\r
580 return TmpNode;\r
581 }\r
582\r
583 TmpNode = TmpNode->mNext;\r
584 }\r
585\r
586 return NULL;\r
587}\r
588\r
589SBufferNode *\r
590CFormPkg::GetNodeBefore(\r
591 IN SBufferNode *CurrentNode\r
592 )\r
593{\r
594 SBufferNode *FirstNode = mBufferNodeQueueHead;\r
595 SBufferNode *LastNode = mBufferNodeQueueHead;\r
596\r
597 while (FirstNode != NULL) {\r
598 if (FirstNode == CurrentNode) {\r
599 break;\r
600 }\r
601\r
602 LastNode = FirstNode;\r
603 FirstNode = FirstNode->mNext;\r
604 }\r
605\r
606 if (FirstNode == NULL) {\r
607 LastNode = NULL;\r
608 }\r
609\r
610 return LastNode;\r
611}\r
612\r
613EFI_VFR_RETURN_CODE\r
614CFormPkg::InsertNodeBefore(\r
615 IN SBufferNode *CurrentNode,\r
616 IN SBufferNode *NewNode\r
617 )\r
618{\r
619 SBufferNode *LastNode = GetNodeBefore (CurrentNode);\r
620\r
621 if (LastNode == NULL) {\r
622 return VFR_RETURN_MISMATCHED;\r
623 }\r
624\r
625 NewNode->mNext = LastNode->mNext;\r
626 LastNode->mNext = NewNode;\r
627\r
628 return VFR_RETURN_SUCCESS;\r
629}\r
630\r
631CHAR8 *\r
632CFormPkg::GetBufAddrBaseOnOffset (\r
633 IN UINT32 Offset\r
634 )\r
635{\r
636 SBufferNode *TmpNode;\r
637 UINT32 TotalBufLen;\r
638 UINT32 CurrentBufLen;\r
639\r
640 TotalBufLen = 0;\r
641\r
642 for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {\r
643 CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;\r
644 if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {\r
645 return TmpNode->mBufferStart + (Offset - TotalBufLen);\r
646 }\r
647\r
648 TotalBufLen += CurrentBufLen;\r
649 }\r
650\r
651 return NULL;\r
652}\r
653\r
654EFI_VFR_RETURN_CODE\r
655CFormPkg::AdjustDynamicInsertOpcode (\r
74bbe31b
DB
656 IN CHAR8 *InserPositionAddr,\r
657 IN CHAR8 *InsertOpcodeAddr,\r
658 IN BOOLEAN CreateOpcodeAfterParsingVfr\r
4afd3d04
LG
659 )\r
660{\r
74bbe31b 661 SBufferNode *InserPositionNode;\r
4afd3d04
LG
662 SBufferNode *InsertOpcodeNode;\r
663 SBufferNode *NewRestoreNodeBegin;\r
664 SBufferNode *NewRestoreNodeEnd;\r
665 SBufferNode *NewLastEndNode;\r
666 SBufferNode *TmpNode;\r
667 UINT32 NeedRestoreCodeLen;\r
668\r
669 NewRestoreNodeEnd = NULL;\r
670\r
74bbe31b 671 InserPositionNode = GetBinBufferNodeForAddr(InserPositionAddr);\r
4afd3d04 672 InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
9b78c54a
HW
673 assert (InserPositionNode != NULL);\r
674 assert (InsertOpcodeNode != NULL);\r
4afd3d04 675\r
74bbe31b 676 if (InserPositionNode == InsertOpcodeNode) {\r
4afd3d04
LG
677 //\r
678 // Create New Node to save the restore opcode.\r
679 //\r
74bbe31b 680 NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;\r
4afd3d04
LG
681 gAdjustOpcodeLen = NeedRestoreCodeLen;\r
682 NewRestoreNodeBegin = CreateNewNode ();\r
683 if (NewRestoreNodeBegin == NULL) {\r
684 return VFR_RETURN_OUT_FOR_RESOURCES;\r
685 }\r
74bbe31b 686 memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);\r
4afd3d04
LG
687 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
688\r
689 //\r
690 // Override the restore buffer data.\r
691 //\r
74bbe31b 692 memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
4afd3d04
LG
693 InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;\r
694 memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);\r
695 } else {\r
696 //\r
697 // Create New Node to save the restore opcode.\r
698 //\r
74bbe31b 699 NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;\r
4afd3d04
LG
700 gAdjustOpcodeLen = NeedRestoreCodeLen;\r
701 NewRestoreNodeBegin = CreateNewNode ();\r
702 if (NewRestoreNodeBegin == NULL) {\r
703 return VFR_RETURN_OUT_FOR_RESOURCES;\r
704 }\r
74bbe31b 705 memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);\r
4afd3d04
LG
706 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
707 //\r
708 // Override the restore buffer data.\r
709 //\r
74bbe31b 710 InserPositionNode->mBufferFree -= NeedRestoreCodeLen;\r
4afd3d04
LG
711 //\r
712 // Link the restore data to new node.\r
713 //\r
74bbe31b 714 NewRestoreNodeBegin->mNext = InserPositionNode->mNext;\r
4afd3d04
LG
715\r
716 //\r
717 // Count the Adjust opcode len.\r
718 //\r
74bbe31b 719 TmpNode = InserPositionNode->mNext;\r
4afd3d04
LG
720 while (TmpNode != InsertOpcodeNode) {\r
721 gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;\r
722 TmpNode = TmpNode->mNext;\r
723 }\r
724\r
725 //\r
726 // Create New Node to save the last node of restore opcode.\r
727 //\r
728 NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
729 gAdjustOpcodeLen += NeedRestoreCodeLen;\r
730 if (NeedRestoreCodeLen > 0) {\r
731 NewRestoreNodeEnd = CreateNewNode ();\r
732 if (NewRestoreNodeEnd == NULL) {\r
733 return VFR_RETURN_OUT_FOR_RESOURCES;\r
734 }\r
735 memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);\r
736 NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;\r
737 //\r
738 // Override the restore buffer data.\r
739 //\r
f51461c8 740 memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
4afd3d04
LG
741 InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
742\r
743 //\r
744 // Insert the last restore data node.\r
745 //\r
746 TmpNode = GetNodeBefore (InsertOpcodeNode);\r
9b78c54a
HW
747 assert (TmpNode != NULL);\r
748\r
74bbe31b 749 if (TmpNode == InserPositionNode) {\r
4afd3d04
LG
750 NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;\r
751 } else {\r
752 TmpNode->mNext = NewRestoreNodeEnd;\r
753 }\r
754 //\r
74bbe31b 755 // Connect the dynamic opcode node to the node after InserPositionNode.\r
4afd3d04 756 //\r
74bbe31b 757 InserPositionNode->mNext = InsertOpcodeNode;\r
4afd3d04
LG
758 }\r
759 }\r
760\r
74bbe31b 761 if (CreateOpcodeAfterParsingVfr) {\r
4afd3d04 762 //\r
74bbe31b
DB
763 // Th new opcodes were created after Parsing Vfr file,\r
764 // so the content in mBufferNodeQueueTail must be the new created opcodes.\r
765 // So connet the NewRestoreNodeBegin to the tail and update the tail node.\r
4afd3d04 766 //\r
4afd3d04
LG
767 mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
768 if (NewRestoreNodeEnd != NULL) {\r
74bbe31b 769 mBufferNodeQueueTail = NewRestoreNodeEnd;\r
4afd3d04 770 } else {\r
74bbe31b 771 mBufferNodeQueueTail = NewRestoreNodeBegin;\r
4afd3d04 772 }\r
74bbe31b
DB
773 } else {\r
774 if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {\r
775 //\r
776 // End form set opcode all in the mBufferNodeQueueTail node.\r
777 //\r
778 NewLastEndNode = CreateNewNode ();\r
779 if (NewLastEndNode == NULL) {\r
780 return VFR_RETURN_OUT_FOR_RESOURCES;\r
781 }\r
782 NewLastEndNode->mBufferStart[0] = 0x29;\r
783 NewLastEndNode->mBufferStart[1] = 0x02;\r
784 NewLastEndNode->mBufferFree += 2;\r
4afd3d04 785\r
74bbe31b
DB
786 mBufferNodeQueueTail->mBufferFree -= 2;\r
787\r
788 mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
789 if (NewRestoreNodeEnd != NULL) {\r
790 NewRestoreNodeEnd->mNext = NewLastEndNode;\r
791 } else {\r
792 NewRestoreNodeBegin->mNext = NewLastEndNode;\r
793 }\r
794\r
795 mBufferNodeQueueTail = NewLastEndNode;\r
796 } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
797 TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
9b78c54a
HW
798 assert (TmpNode != NULL);\r
799\r
74bbe31b
DB
800 TmpNode->mNext = NewRestoreNodeBegin;\r
801 if (NewRestoreNodeEnd != NULL) {\r
802 NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
803 } else {\r
804 NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;\r
805 }\r
4afd3d04
LG
806 }\r
807 }\r
74bbe31b 808 mCurrBufferNode = mBufferNodeQueueTail;\r
4afd3d04
LG
809 return VFR_RETURN_SUCCESS;\r
810}\r
811\r
30fdf114
LG
812EFI_VFR_RETURN_CODE\r
813CFormPkg::DeclarePendingQuestion (\r
814 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,\r
815 IN CVfrDataStorage &lCVfrDataStorage,\r
816 IN CVfrQuestionDB &lCVfrQuestionDB,\r
817 IN EFI_GUID *LocalFormSetGuid,\r
4afd3d04
LG
818 IN UINT32 LineNo,\r
819 OUT CHAR8 **InsertOpcodeAddr\r
30fdf114
LG
820 )\r
821{\r
822 SPendingAssign *pNode;\r
823 CHAR8 *VarStr;\r
824 UINT32 ArrayIdx;\r
825 CHAR8 FName[MAX_NAME_LEN];\r
b36d134f
LG
826 CHAR8 *SName;\r
827 CHAR8 *NewStr;\r
61eb9834 828 UINT32 ShrinkSize = 0;\r
30fdf114
LG
829 EFI_VFR_RETURN_CODE ReturnCode;\r
830 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
42c808d4
DB
831 UINT8 LFlags;\r
832 UINT32 MaxValue;\r
833 CIfrGuid *GuidObj = NULL;\r
30fdf114 834\r
b36d134f
LG
835 //\r
836 // Declare all questions as Numeric in DisableIf True\r
837 //\r
838 // DisableIf\r
839 CIfrDisableIf DIObj;\r
840 DIObj.SetLineNo (LineNo);\r
5397bd42 841 *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();\r
f7496d71 842\r
b36d134f
LG
843 //TrueOpcode\r
844 CIfrTrue TObj (LineNo);\r
845\r
846 // Declare Numeric qeustion for each undefined question.\r
30fdf114
LG
847 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
848 if (pNode->mFlag == PENDING) {\r
f7496d71 849 EFI_VARSTORE_INFO Info;\r
4afd3d04 850 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
30fdf114
LG
851 //\r
852 // Register this question, assume it is normal question, not date or time question\r
853 //\r
854 VarStr = pNode->mKey;\r
855 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);\r
856 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
857 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
858 return ReturnCode;\r
859 }\r
f7496d71 860\r
30fdf114
LG
861#ifdef VFREXP_DEBUG\r
862 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
863#endif\r
864 //\r
865 // Get Question Info, framework vfr VarName == StructName\r
866 //\r
867 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);\r
868 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
869 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");\r
870 return ReturnCode;\r
871 }\r
872 //\r
873 // Get VarStoreType\r
874 //\r
4afd3d04 875 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
30fdf114
LG
876 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
877 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
878 return ReturnCode;\r
879 }\r
f7496d71 880 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);\r
30fdf114
LG
881\r
882 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
883 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
884 } else {\r
885 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
886 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
42c808d4 887 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {\r
30fdf114 888 VarStr = pNode->mKey;\r
b36d134f 889 //convert VarStr with store name to VarStr with structure name\r
4afd3d04 890 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
b36d134f
LG
891 if (ReturnCode == VFR_RETURN_SUCCESS) {\r
892 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
893 NewStr[0] = '\0';\r
894 strcpy (NewStr, SName);\r
895 strcat (NewStr, VarStr + strlen (FName));\r
42c808d4 896 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);\r
fd542523 897 delete[] NewStr;\r
b36d134f 898 }\r
30fdf114
LG
899 } else {\r
900 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
901 }\r
902 }\r
903 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
904 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
905 return ReturnCode;\r
906 }\r
0d2711a6 907 //\r
42c808d4 908 // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.\r
0d2711a6 909 //\r
42c808d4
DB
910 if (Info.mIsBitVar) {\r
911 GuidObj = new CIfrGuid(0);\r
912 GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);\r
913 GuidObj->SetLineNo(LineNo);\r
0d2711a6 914 }\r
42c808d4
DB
915\r
916 CIfrNumeric CNObj;\r
917 CNObj.SetLineNo (LineNo);\r
918 CNObj.SetPrompt (0x0);\r
919 CNObj.SetHelp (0x0);\r
920 CNObj.SetQuestionId (QId);\r
921 CNObj.SetVarStoreInfo (&Info);\r
922\r
2bcc713e 923 //\r
42c808d4 924 // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.\r
2bcc713e 925 //\r
42c808d4
DB
926 if (Info.mIsBitVar) {\r
927 MaxValue = (1 << Info.mVarTotalSize) -1;\r
928 CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);\r
4afd3d04 929 ShrinkSize = 12;\r
42c808d4
DB
930 LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);\r
931 CNObj.SetFlagsForBitField (0, LFlags);\r
932 } else {\r
933 //\r
934 // Numeric doesn't support BOOLEAN data type.\r
935 // BOOLEAN type has the same data size to UINT8.\r
936 //\r
937 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
938 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
939 }\r
940 CNObj.SetFlags (0, Info.mVarType);\r
941 //\r
fb0b35e0 942 // Use maximum value not to limit the valid value for the undefined question.\r
42c808d4
DB
943 //\r
944 switch (Info.mVarType) {\r
945 case EFI_IFR_TYPE_NUM_SIZE_64:\r
946 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
947 ShrinkSize = 0;\r
948 break;\r
949 case EFI_IFR_TYPE_NUM_SIZE_32:\r
950 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
951 ShrinkSize = 12;\r
952 break;\r
953 case EFI_IFR_TYPE_NUM_SIZE_16:\r
954 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
955 ShrinkSize = 18;\r
956 break;\r
957 case EFI_IFR_TYPE_NUM_SIZE_8:\r
958 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
959 ShrinkSize = 21;\r
960 break;\r
961 default:\r
962 break;\r
963 }\r
2bcc713e 964 }\r
4afd3d04 965 CNObj.ShrinkBinSize (ShrinkSize);\r
30fdf114
LG
966\r
967 //\r
968 // For undefined Efi VarStore type question\r
969 // Append the extended guided opcode to contain VarName\r
970 //\r
b36d134f 971 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
30fdf114
LG
972 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
973 CVNObj.SetLineNo (LineNo);\r
974 }\r
4afd3d04 975\r
30fdf114
LG
976 //\r
977 // End for Numeric\r
978 //\r
42c808d4 979 CIfrEnd CEObj;\r
30fdf114 980 CEObj.SetLineNo (LineNo);\r
42c808d4
DB
981 //\r
982 // End for Guided opcode\r
983 //\r
984 if (GuidObj != NULL) {\r
985 CIfrEnd CEObjGuid;\r
986 CEObjGuid.SetLineNo (LineNo);\r
987 GuidObj->SetScope(1);\r
988 delete GuidObj;\r
989 GuidObj = NULL;\r
990 }\r
30fdf114
LG
991 }\r
992 }\r
b36d134f
LG
993\r
994 //\r
995 // End for DisableIf\r
996 //\r
997 CIfrEnd SEObj;\r
998 SEObj.SetLineNo (LineNo);\r
999\r
30fdf114
LG
1000 return VFR_RETURN_SUCCESS;\r
1001}\r
1002\r
1003CFormPkg gCFormPkg;\r
1004\r
1005SIfrRecord::SIfrRecord (\r
1006 VOID\r
1007 )\r
1008{\r
1009 mIfrBinBuf = NULL;\r
1010 mBinBufLen = 0;\r
1011 mLineNo = 0xFFFFFFFF;\r
1012 mOffset = 0xFFFFFFFF;\r
1013 mNext = NULL;\r
1014}\r
1015\r
1016SIfrRecord::~SIfrRecord (\r
1017 VOID\r
1018 )\r
1019{\r
1020 if (mIfrBinBuf != NULL) {\r
1021 //delete mIfrBinBuf;\r
1022 mIfrBinBuf = NULL;\r
1023 }\r
1024 mLineNo = 0xFFFFFFFF;\r
1025 mOffset = 0xFFFFFFFF;\r
1026 mBinBufLen = 0;\r
1027 mNext = NULL;\r
1028}\r
1029\r
1030CIfrRecordInfoDB::CIfrRecordInfoDB (\r
1031 VOID\r
1032 )\r
1033{\r
1034 mSwitch = TRUE;\r
1035 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
1036 mIfrRecordListHead = NULL;\r
1037 mIfrRecordListTail = NULL;\r
74bbe31b
DB
1038 mAllDefaultTypeCount = 0;\r
1039 for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {\r
1040 mAllDefaultIdArray[i] = 0xffff;\r
1041 }\r
30fdf114
LG
1042}\r
1043\r
1044CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
1045 VOID\r
1046 )\r
1047{\r
1048 SIfrRecord *pNode;\r
1049\r
1050 while (mIfrRecordListHead != NULL) {\r
1051 pNode = mIfrRecordListHead;\r
1052 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
1053 delete pNode;\r
1054 }\r
1055}\r
1056\r
1057SIfrRecord *\r
1058CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
1059 IN UINT32 RecordIdx\r
1060 )\r
1061{\r
1062 UINT32 Idx;\r
1063 SIfrRecord *pNode = NULL;\r
1064\r
1065 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
1066 return NULL;\r
1067 }\r
1068\r
1069 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
1070 (Idx != RecordIdx) && (pNode != NULL);\r
1071 Idx++, pNode = pNode->mNext)\r
1072 ;\r
1073\r
1074 return pNode;\r
1075}\r
1076\r
1077UINT32\r
1078CIfrRecordInfoDB::IfrRecordRegister (\r
1079 IN UINT32 LineNo,\r
1080 IN CHAR8 *IfrBinBuf,\r
1081 IN UINT8 BinBufLen,\r
1082 IN UINT32 Offset\r
1083 )\r
1084{\r
1085 SIfrRecord *pNew;\r
1086\r
1087 if (mSwitch == FALSE) {\r
1088 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1089 }\r
1090\r
1091 if ((pNew = new SIfrRecord) == NULL) {\r
1092 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1093 }\r
1094\r
1095 if (mIfrRecordListHead == NULL) {\r
1096 mIfrRecordListHead = pNew;\r
1097 mIfrRecordListTail = pNew;\r
1098 } else {\r
1099 mIfrRecordListTail->mNext = pNew;\r
1100 mIfrRecordListTail = pNew;\r
1101 }\r
1102 mRecordCount++;\r
1103\r
1104 return mRecordCount;\r
1105}\r
1106\r
1107VOID\r
1108CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
1109 IN UINT32 RecordIdx,\r
1110 IN UINT32 LineNo,\r
1111 IN CHAR8 *BinBuf,\r
1112 IN UINT8 BinBufLen,\r
1113 IN UINT32 Offset\r
1114 )\r
1115{\r
1116 SIfrRecord *pNode;\r
fd171542 1117 SIfrRecord *Prev;\r
30fdf114
LG
1118\r
1119 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
1120 return;\r
1121 }\r
1122\r
fd171542 1123 if (LineNo == 0) {\r
1124 //\r
1125 // Line number is not specified explicitly, try to use line number of previous opcode\r
1126 //\r
1127 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
1128 if (Prev != NULL) {\r
1129 LineNo = Prev->mLineNo;\r
1130 }\r
1131 }\r
1132\r
30fdf114
LG
1133 pNode->mLineNo = LineNo;\r
1134 pNode->mOffset = Offset;\r
1135 pNode->mBinBufLen = BinBufLen;\r
1136 pNode->mIfrBinBuf = BinBuf;\r
1137\r
1138}\r
1139\r
1140VOID\r
1141CIfrRecordInfoDB::IfrRecordOutput (\r
1142 OUT PACKAGE_DATA &TBuffer\r
1143 )\r
1144{\r
1145 CHAR8 *Temp;\r
f7496d71 1146 SIfrRecord *pNode;\r
30fdf114
LG
1147\r
1148 if (TBuffer.Buffer != NULL) {\r
f7e98581 1149 delete[] TBuffer.Buffer;\r
30fdf114
LG
1150 }\r
1151\r
1152 TBuffer.Size = 0;\r
1153 TBuffer.Buffer = NULL;\r
1154\r
1155\r
1156 if (mSwitch == FALSE) {\r
1157 return;\r
f7496d71
LG
1158 }\r
1159\r
30fdf114
LG
1160 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1161 TBuffer.Size += pNode->mBinBufLen;\r
1162 }\r
f7496d71 1163\r
30fdf114
LG
1164 if (TBuffer.Size != 0) {\r
1165 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
1166 } else {\r
1167 return;\r
1168 }\r
f7496d71 1169\r
30fdf114
LG
1170 Temp = TBuffer.Buffer;\r
1171\r
1172 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1173 if (pNode->mIfrBinBuf != NULL) {\r
1174 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
1175 Temp += pNode->mBinBufLen;\r
1176 }\r
1177 }\r
1178\r
f7496d71
LG
1179 return;\r
1180}\r
30fdf114
LG
1181\r
1182VOID\r
1183CIfrRecordInfoDB::IfrRecordOutput (\r
1184 IN FILE *File,\r
1185 IN UINT32 LineNo\r
1186 )\r
1187{\r
1188 SIfrRecord *pNode;\r
1189 UINT8 Index;\r
1190 UINT32 TotalSize;\r
1191\r
1192 if (mSwitch == FALSE) {\r
1193 return;\r
1194 }\r
1195\r
1196 if (File == NULL) {\r
1197 return;\r
1198 }\r
1199\r
1200 TotalSize = 0;\r
1201\r
1202 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1203 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
1204 fprintf (File, ">%08X: ", pNode->mOffset);\r
1205 TotalSize += pNode->mBinBufLen;\r
1206 if (pNode->mIfrBinBuf != NULL) {\r
1207 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
1208 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
1209 }\r
1210 }\r
1211 fprintf (File, "\n");\r
1212 }\r
1213 }\r
f7496d71 1214\r
30fdf114
LG
1215 if (LineNo == 0) {\r
1216 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
1217 }\r
1218}\r
1219\r
1220//\r
1221// for framework vfr file\r
1222// adjust opcode sequence for uefi IFR format\r
1223// adjust inconsistent and varstore into the right position.\r
1224//\r
1225BOOLEAN\r
1226CIfrRecordInfoDB::CheckQuestionOpCode (\r
1227 IN UINT8 OpCode\r
1228 )\r
1229{\r
1230 switch (OpCode) {\r
1231 case EFI_IFR_CHECKBOX_OP:\r
1232 case EFI_IFR_NUMERIC_OP:\r
1233 case EFI_IFR_PASSWORD_OP:\r
1234 case EFI_IFR_ONE_OF_OP:\r
1235 case EFI_IFR_ACTION_OP:\r
1236 case EFI_IFR_STRING_OP:\r
1237 case EFI_IFR_DATE_OP:\r
1238 case EFI_IFR_TIME_OP:\r
1239 case EFI_IFR_ORDERED_LIST_OP:\r
bec3a181 1240 case EFI_IFR_REF_OP:\r
30fdf114
LG
1241 return TRUE;\r
1242 default:\r
1243 return FALSE;\r
1244 }\r
1245}\r
1246\r
1247BOOLEAN\r
1248CIfrRecordInfoDB::CheckIdOpCode (\r
1249 IN UINT8 OpCode\r
1250 )\r
1251{\r
1252 switch (OpCode) {\r
1253 case EFI_IFR_EQ_ID_VAL_OP:\r
1254 case EFI_IFR_EQ_ID_ID_OP:\r
64b2609f 1255 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
30fdf114
LG
1256 case EFI_IFR_QUESTION_REF1_OP:\r
1257 return TRUE;\r
1258 default:\r
1259 return FALSE;\r
1260 }\r
f7496d71 1261}\r
30fdf114
LG
1262\r
1263EFI_QUESTION_ID\r
1264CIfrRecordInfoDB::GetOpcodeQuestionId (\r
1265 IN EFI_IFR_OP_HEADER *OpHead\r
1266 )\r
1267{\r
1268 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
f7496d71 1269\r
30fdf114 1270 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
f7496d71 1271\r
30fdf114
LG
1272 return QuestionHead->QuestionId;\r
1273}\r
1274\r
4afd3d04
LG
1275SIfrRecord *\r
1276CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
1277 IN UINT32 Offset\r
1278 )\r
1279{\r
1280 SIfrRecord *pNode = NULL;\r
1281\r
1282 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1283 if (pNode->mOffset == Offset) {\r
1284 return pNode;\r
1285 }\r
1286 }\r
1287\r
1288 return pNode;\r
1289}\r
1290\r
74bbe31b 1291/**\r
4afd3d04
LG
1292 Add just the op code position.\r
1293\r
74bbe31b
DB
1294 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,\r
1295 so pDynamicOpcodeNodes is before mIfrRecordListTail.\r
1296\r
4afd3d04 1297 From\r
74bbe31b
DB
1298\r
1299 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|\r
1300\r
4afd3d04 1301 To\r
4afd3d04 1302\r
74bbe31b
DB
1303 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|\r
1304\r
1305 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,\r
1306 so new records are appennded to the end of OriginalIfrRecordListTail.\r
1307\r
1308 From\r
1309\r
1310 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|\r
1311\r
1312 To\r
1313\r
1314 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|\r
1315\r
1316\r
1317 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
1318\r
1319**/\r
4afd3d04
LG
1320BOOLEAN\r
1321CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
74bbe31b 1322 IN BOOLEAN CreateOpcodeAfterParsingVfr\r
4afd3d04
LG
1323 )\r
1324{\r
1325 UINT32 OpcodeOffset;\r
1326 SIfrRecord *pNode, *pPreNode;\r
74bbe31b
DB
1327 SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;\r
1328 SIfrRecord *pNodeBeforeDynamic;\r
1329\r
61eb9834 1330 pPreNode = NULL;\r
74bbe31b
DB
1331 pAdjustNode = NULL;\r
1332 pNodeBeforeDynamic = NULL;\r
1333 OpcodeOffset = 0;\r
4afd3d04
LG
1334\r
1335 //\r
74bbe31b
DB
1336 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,\r
1337 // and the node before pDynamicOpcodeNode.\r
4afd3d04 1338 //\r
74bbe31b 1339 for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {\r
4afd3d04 1340 if (OpcodeOffset == gAdjustOpcodeOffset) {\r
74bbe31b
DB
1341 pAdjustNode = pNode;\r
1342 pNodeBeforeAdjust = pPreNode;\r
4afd3d04 1343 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
74bbe31b
DB
1344 pNodeBeforeDynamic = pPreNode;\r
1345 }\r
1346 if (pNode->mNext != NULL) {\r
1347 pPreNode = pNode;\r
4afd3d04 1348 }\r
4afd3d04
LG
1349 OpcodeOffset += pNode->mBinBufLen;\r
1350 }\r
1351\r
1352 //\r
74bbe31b 1353 // Check the nodes whether exist.\r
4afd3d04 1354 //\r
9b78c54a 1355 if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {\r
4afd3d04
LG
1356 return FALSE;\r
1357 }\r
1358\r
1359 //\r
1360 // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
1361 //\r
74bbe31b
DB
1362 pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;\r
1363 if (CreateOpcodeAfterParsingVfr) {\r
1364 //\r
1365 // mIfrRecordListTail is the end of pDynamicNode (Case2).\r
1366 //\r
1367 mIfrRecordListTail->mNext = pAdjustNode;\r
1368 mIfrRecordListTail = pNodeBeforeDynamic;\r
1369 mIfrRecordListTail->mNext = NULL;\r
1370 } else {\r
1371 //\r
1372 //pPreNode is the end of pDynamicNode(Case1).\r
1373 //\r
1374 pPreNode->mNext = pAdjustNode;\r
1375 pNodeBeforeDynamic->mNext = mIfrRecordListTail;\r
1376 }\r
4afd3d04
LG
1377\r
1378 return TRUE;\r
1379}\r
1380\r
74bbe31b
DB
1381/**\r
1382 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.\r
1383\r
1384 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
1385\r
1386**/\r
1387VOID\r
1388CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (\r
1389 IN BOOLEAN CreateOpcodeAfterParsingVfr\r
1390 )\r
1391{\r
1392 SIfrRecord *pRecord;\r
1393\r
1394 //\r
1395 // Base on the original offset info to update the record list.\r
1396 //\r
1397 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {\r
00de920a 1398 gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");\r
74bbe31b
DB
1399 }\r
1400\r
1401 //\r
1402 // Base on the opcode binary length to recalculate the offset for each opcode.\r
1403 //\r
1404 IfrAdjustOffsetForRecord();\r
1405\r
1406 //\r
1407 // Base on the offset to find the binary address.\r
1408 //\r
1409 pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);\r
1410 while (pRecord != NULL) {\r
1411 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);\r
1412 pRecord = pRecord->mNext;\r
1413 }\r
1414}\r
1415\r
1416\r
4afd3d04
LG
1417VOID\r
1418CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
1419 VOID\r
1420 )\r
1421{\r
1422 UINT32 OpcodeOffset;\r
1423 SIfrRecord *pNode;\r
1424\r
1425 OpcodeOffset = 0;\r
1426 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1427 pNode->mOffset = OpcodeOffset;\r
1428 OpcodeOffset += pNode->mBinBufLen;\r
1429 }\r
1430}\r
1431\r
30fdf114
LG
1432EFI_VFR_RETURN_CODE\r
1433CIfrRecordInfoDB::IfrRecordAdjust (\r
1434 VOID\r
1435 )\r
1436{\r
1437 SIfrRecord *pNode, *preNode;\r
1438 SIfrRecord *uNode, *tNode;\r
1439 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
1440 EFI_QUESTION_ID QuestionId;\r
1441 UINT32 StackCount;\r
1442 UINT32 QuestionScope;\r
30fdf114
LG
1443 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
1444 EFI_VFR_RETURN_CODE Status;\r
1445\r
1446 //\r
1447 // Init local variable\r
1448 //\r
1449 Status = VFR_RETURN_SUCCESS;\r
1450 pNode = mIfrRecordListHead;\r
1451 preNode = pNode;\r
1452 QuestionScope = 0;\r
1453 while (pNode != NULL) {\r
1454 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
f7496d71 1455\r
30fdf114
LG
1456 //\r
1457 // make sure the inconsistent opcode in question scope\r
1458 //\r
1459 if (QuestionScope > 0) {\r
1460 QuestionScope += OpHead->Scope;\r
1461 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1462 QuestionScope --;\r
1463 }\r
1464 }\r
f7496d71 1465\r
30fdf114
LG
1466 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1467 QuestionScope = 1;\r
1468 }\r
1469 //\r
1470 // for the inconsistent opcode not in question scope, adjust it\r
1471 //\r
1472 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1473 //\r
1474 // for inconsistent opcode not in question scope\r
1475 //\r
1476\r
1477 //\r
f7496d71 1478 // Count inconsistent opcode Scope\r
30fdf114
LG
1479 //\r
1480 StackCount = OpHead->Scope;\r
1481 QuestionId = EFI_QUESTION_ID_INVALID;\r
1482 tNode = pNode;\r
1483 while (tNode != NULL && StackCount > 0) {\r
1484 tNode = tNode->mNext;\r
1485 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1486 //\r
1487 // Calculate Scope Number\r
1488 //\r
1489 StackCount += tOpHead->Scope;\r
1490 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1491 StackCount --;\r
1492 }\r
1493 //\r
1494 // by IdEqual opcode to get QuestionId\r
1495 //\r
f7496d71 1496 if (QuestionId == EFI_QUESTION_ID_INVALID &&\r
30fdf114
LG
1497 CheckIdOpCode (tOpHead->OpCode)) {\r
1498 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1499 }\r
1500 }\r
1501 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1502 //\r
1503 // report error; not found\r
1504 //\r
1505 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1506 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1507 Status = VFR_RETURN_MISMATCHED;\r
1508 break;\r
1509 }\r
1510 //\r
1511 // extract inconsistent opcode list\r
fb0b35e0 1512 // pNode is Inconsistent opcode, tNode is End Opcode\r
30fdf114 1513 //\r
f7496d71 1514\r
30fdf114
LG
1515 //\r
1516 // insert inconsistent opcode list into the right question scope by questionid\r
1517 //\r
1518 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1519 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
f7496d71 1520 if (CheckQuestionOpCode (tOpHead->OpCode) &&\r
30fdf114
LG
1521 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1522 break;\r
1523 }\r
1524 }\r
1525 //\r
1526 // insert inconsistent opcode list and check LATE_CHECK flag\r
1527 //\r
1528 if (uNode != NULL) {\r
1529 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1530 //\r
1531 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1532 //\r
1533 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1534 }\r
f7496d71 1535\r
30fdf114
LG
1536 //\r
1537 // skip the default storage for Date and Time\r
1538 //\r
1539 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1540 uNode = uNode->mNext;\r
1541 }\r
1542\r
1543 preNode->mNext = tNode->mNext;\r
1544 tNode->mNext = uNode->mNext;\r
1545 uNode->mNext = pNode;\r
1546 //\r
1547 // reset pNode to head list, scan the whole list again.\r
1548 //\r
1549 pNode = mIfrRecordListHead;\r
1550 preNode = pNode;\r
1551 QuestionScope = 0;\r
1552 continue;\r
1553 } else {\r
1554 //\r
1555 // not found matched question id, report error\r
1556 //\r
1557 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1558 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1559 Status = VFR_RETURN_MISMATCHED;\r
1560 break;\r
1561 }\r
f7496d71 1562 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||\r
30fdf114
LG
1563 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1564 //\r
1565 // for new added group of varstore opcode\r
1566 //\r
1567 tNode = pNode;\r
1568 while (tNode->mNext != NULL) {\r
1569 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
f7496d71 1570 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&\r
30fdf114 1571 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
f7496d71 1572 break;\r
30fdf114
LG
1573 }\r
1574 tNode = tNode->mNext;\r
1575 }\r
1576\r
1577 if (tNode->mNext == NULL) {\r
1578 //\r
1579 // invalid IfrCode, IfrCode end by EndOpCode\r
f7496d71 1580 //\r
30fdf114
LG
1581 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1582 Status = VFR_RETURN_MISMATCHED;\r
1583 break;\r
1584 }\r
f7496d71 1585\r
30fdf114
LG
1586 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1587 //\r
1588 // not new added varstore, which are not needed to be adjust.\r
1589 //\r
1590 preNode = tNode;\r
1591 pNode = tNode->mNext;\r
f7496d71 1592 continue;\r
30fdf114
LG
1593 } else {\r
1594 //\r
f7496d71 1595 // move new added varstore opcode to the position befor form opcode\r
30fdf114
LG
1596 // varstore opcode between pNode and tNode\r
1597 //\r
1598\r
1599 //\r
1600 // search form opcode from begin\r
1601 //\r
1602 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1603 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1604 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1605 break;\r
1606 }\r
1607 }\r
1608 //\r
1609 // Insert varstore opcode beform form opcode if form opcode is found\r
1610 //\r
1611 if (uNode->mNext != NULL) {\r
1612 preNode->mNext = tNode->mNext;\r
1613 tNode->mNext = uNode->mNext;\r
1614 uNode->mNext = pNode;\r
1615 //\r
1616 // reset pNode to head list, scan the whole list again.\r
1617 //\r
1618 pNode = mIfrRecordListHead;\r
1619 preNode = pNode;\r
1620 QuestionScope = 0;\r
1621 continue;\r
1622 } else {\r
1623 //\r
1624 // not found form, continue scan IfrRecord list\r
1625 //\r
1626 preNode = tNode;\r
1627 pNode = tNode->mNext;\r
1628 continue;\r
1629 }\r
1630 }\r
1631 }\r
1632 //\r
1633 // next node\r
1634 //\r
1635 preNode = pNode;\r
f7496d71 1636 pNode = pNode->mNext;\r
30fdf114 1637 }\r
f7496d71 1638\r
30fdf114
LG
1639 //\r
1640 // Update Ifr Opcode Offset\r
1641 //\r
1642 if (Status == VFR_RETURN_SUCCESS) {\r
4afd3d04 1643 IfrAdjustOffsetForRecord ();\r
30fdf114
LG
1644 }\r
1645 return Status;\r
1646}\r
1647\r
74bbe31b
DB
1648/**\r
1649 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not\r
1650 given by expression, should save the default info for the Buffer VarStore.\r
1651\r
1652 @param DefaultId The default id.\r
1653 @param pQuestionNode Point to the question opcode node.\r
1654 @param Value The default value.\r
1655**/\r
1656VOID\r
1657CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (\r
1658 IN UINT16 DefaultId,\r
1659 IN SIfrRecord *pQuestionNode,\r
1660 IN EFI_IFR_TYPE_VALUE Value\r
1661 )\r
1662{\r
1663 CHAR8 *VarStoreName = NULL;\r
1664 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1665 EFI_GUID *VarGuid = NULL;\r
1666 EFI_VARSTORE_INFO VarInfo;\r
1667 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1668 EFI_IFR_OP_HEADER *pQuestionOpHead;\r
1669\r
1670 pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
1671 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);\r
1672\r
1673 //\r
1674 // Get the Var Store name and type.\r
1675 //\r
1676 gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);\r
1677 VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);\r
1678 VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);\r
1679\r
1680 //\r
1681 // Only for Buffer storage need to save the default info in the storage.\r
1682 // Other type storage, just return.\r
1683 //\r
1684 if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {\r
1685 return;\r
1686 } else {\r
1687 VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;\r
1688 VarInfo.mVarStoreId = QuestionHead->VarStoreId;\r
1689 }\r
1690\r
1691 //\r
1692 // Get the buffer storage info about this question.\r
1693 //\r
1694 gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);\r
1695\r
1696 //\r
1697 // Add action.\r
1698 //\r
1699 gCVfrDefaultStore.BufferVarStoreAltConfigAdd (\r
1700 DefaultId,\r
1701 VarInfo,\r
1702 VarStoreName,\r
1703 VarGuid,\r
1704 VarInfo.mVarType,\r
1705 Value\r
1706 );\r
1707}\r
1708\r
1709/**\r
1710 Record the number and default id of all defaultstore opcode.\r
1711\r
1712**/\r
1713VOID\r
1714CIfrRecordInfoDB::IfrGetDefaultStoreInfo (\r
1715 VOID\r
1716 )\r
1717{\r
1718 SIfrRecord *pNode;\r
1719 EFI_IFR_OP_HEADER *pOpHead;\r
1720 EFI_IFR_DEFAULTSTORE *DefaultStore;\r
1721\r
1722 pNode = mIfrRecordListHead;\r
1723 mAllDefaultTypeCount = 0;\r
1724\r
1725 while (pNode != NULL) {\r
1726 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1727\r
1728 if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){\r
1729 DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;\r
1730 mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;\r
1731 }\r
1732 pNode = pNode->mNext;\r
1733 }\r
1734}\r
1735\r
1736/**\r
1737 Create new default opcode record.\r
1738\r
1739 @param Size The new default opcode size.\r
1740 @param DefaultId The new default id.\r
1741 @param Type The new default type.\r
1742 @param LineNo The line number of the new record.\r
1743 @param Value The new default value.\r
1744\r
1745**/\r
1746VOID\r
1747CIfrRecordInfoDB::IfrCreateDefaultRecord(\r
1748 IN UINT8 Size,\r
1749 IN UINT16 DefaultId,\r
1750 IN UINT8 Type,\r
1751 IN UINT32 LineNo,\r
1752 IN EFI_IFR_TYPE_VALUE Value\r
1753 )\r
1754{\r
1755 CIfrDefault *DObj;\r
1756 CIfrDefault2 *DObj2;\r
1757\r
1758 DObj = NULL;\r
1759 DObj2 = NULL;\r
1760\r
1761 if (Type == EFI_IFR_TYPE_OTHER) {\r
1762 DObj2 = new CIfrDefault2 (Size);\r
1763 DObj2->SetDefaultId(DefaultId);\r
1764 DObj2->SetType(Type);\r
1765 DObj2->SetLineNo(LineNo);\r
1766 DObj2->SetScope (1);\r
1767 delete DObj2;\r
1768 } else {\r
1769 DObj = new CIfrDefault (Size);\r
1770 DObj->SetDefaultId(DefaultId);\r
1771 DObj->SetType(Type);\r
1772 DObj->SetLineNo(LineNo);\r
1773 DObj->SetValue (Value);\r
1774 delete DObj;\r
1775 }\r
1776}\r
1777\r
1778/**\r
1779 Create new default opcode for question base on the QuestionDefaultInfo.\r
1780\r
1781 @param pQuestionNode Point to the question opcode Node.\r
1782 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.\r
1783\r
1784**/\r
1785VOID\r
1786CIfrRecordInfoDB::IfrCreateDefaultForQuestion (\r
1787 IN SIfrRecord *pQuestionNode,\r
1788 IN QuestionDefaultRecord *QuestionDefaultInfo\r
1789 )\r
1790{\r
1791 EFI_IFR_OP_HEADER *pOpHead;\r
1792 EFI_IFR_DEFAULT *Default;\r
1793 SIfrRecord *pSNode;\r
1794 SIfrRecord *pENode;\r
1795 SIfrRecord *pDefaultNode;\r
1796 CIfrObj *Obj;\r
1797 CHAR8 *ObjBinBuf;\r
1798 UINT8 ScopeCount;\r
1799 UINT8 OpcodeNumber;\r
1800 UINT8 OpcodeCount;\r
1801 UINT8 DefaultSize;\r
1802 EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;\r
1803 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;\r
1804\r
1805 CheckBoxDefaultValue.b = 1;\r
1806 pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
1807 ScopeCount = 0;\r
1808 OpcodeCount = 0;\r
1809 Obj = NULL;\r
1810\r
1811 //\r
1812 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1813 //\r
1814 gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;\r
1815 //\r
1816 // Case 1:\r
1817 // For oneof, the default with smallest default id is given by the option flag.\r
1818 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).\r
1819 //\r
1820 if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
1821 DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;\r
1822 DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);\r
1823 DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
1824 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1825 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1826 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);\r
1827 //\r
1828 // Save the new created default in the buffer storage.\r
1829 //\r
1830 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);\r
1831 }\r
1832 }\r
1833 return;\r
1834 }\r
1835\r
1836 //\r
1837 // Case2:\r
1838 // For checkbox, the default with smallest default id is given by the question flag.\r
1839 // And create the missing defaults with true value.\r
1840 //\r
1841 if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
1842 DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);\r
1843 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1844 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1845 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);\r
1846 //\r
1847 // Save the new created default.\r
1848 //\r
1849 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);\r
1850 }\r
1851 }\r
1852 return;\r
1853 }\r
1854\r
1855 //\r
1856 // Case3:\r
1857 // The default with smallest default id is given by the default opcode.\r
1858 // So create the missing defaults base on the value in the default opcode.\r
1859 //\r
1860\r
1861 //\r
1862 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.\r
1863 //\r
1864 pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;\r
1865 Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;\r
1866 //\r
1867 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1868 //\r
1869 gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;\r
1870\r
1871 if (Default->Type == EFI_IFR_TYPE_OTHER) {\r
1872 //\r
1873 // EFI_IFR_DEFAULT_2 opcode.\r
1874 //\r
1875 // Point to the first expression opcode.\r
1876 //\r
1877 pSNode = pDefaultNode->mNext;\r
61eb9834 1878 pENode = NULL;\r
74bbe31b
DB
1879 ScopeCount++;\r
1880 //\r
1881 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)\r
1882 //\r
1883 while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {\r
1884 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1885 if (pOpHead->Scope == 1) {\r
1886 ScopeCount++;\r
1887 }\r
1888 if (pOpHead->OpCode == EFI_IFR_END_OP) {\r
1889 ScopeCount--;\r
1890 }\r
1891 pENode = pSNode;\r
1892 pSNode = pSNode->mNext;\r
1893 OpcodeCount++;\r
1894 }\r
9b78c54a
HW
1895\r
1896 assert (pSNode);\r
1897 assert (pENode);\r
1898\r
74bbe31b
DB
1899 //\r
1900 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1901 //\r
1902 gAdjustOpcodeOffset = pSNode->mOffset;\r
1903 //\r
1904 // Create new default opcode node for missing default.\r
1905 //\r
1906 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1907 OpcodeNumber = OpcodeCount;\r
1908 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1909 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);\r
1910 //\r
1911 // Point to the first expression opcode node.\r
1912 //\r
1913 pSNode = pDefaultNode->mNext;\r
1914 //\r
1915 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.\r
1916 //\r
1917 while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {\r
1918 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1919 Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);\r
9b78c54a 1920 assert (Obj != NULL);\r
74bbe31b 1921 Obj->SetLineNo (pSNode->mLineNo);\r
5397bd42 1922 ObjBinBuf = Obj->GetObjBinAddr<CHAR8>();\r
74bbe31b
DB
1923 memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);\r
1924 delete Obj;\r
1925 pSNode = pSNode->mNext;\r
1926 }\r
1927 }\r
1928 }\r
1929 } else {\r
1930 //\r
1931 // EFI_IFR_DEFAULT opcode.\r
1932 //\r
1933 // Create new default opcode node for missing default.\r
1934 //\r
1935 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1936 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1937 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);\r
1938 //\r
1939 // Save the new created default in the buffer storage..\r
1940 //\r
1941 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);\r
1942 }\r
1943 }\r
1944 }\r
1945}\r
1946\r
1947/**\r
1948 Parse the default information in a question, get the QuestionDefaultInfo.\r
1949\r
1950 @param pQuestionNode Point to the question record Node.\r
1951 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.\r
1952**/\r
1953VOID\r
1954CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(\r
1955 IN SIfrRecord *pQuestionNode,\r
1956 OUT QuestionDefaultRecord *QuestionDefaultInfo\r
1957 )\r
1958{\r
1959 SIfrRecord *pSNode;\r
1960 EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;\r
1961 EFI_IFR_OP_HEADER *pSOpHead;\r
1962 EFI_IFR_CHECKBOX *CheckBoxOpcode;\r
1963 EFI_IFR_DEFAULT *DefaultOpcode;\r
1964 BOOLEAN IsOneOfOpcode;\r
1965 UINT16 SmallestDefaultId;\r
1966 UINT8 ScopeCount;\r
1967\r
1968 SmallestDefaultId = 0xffff;\r
1969 IsOneOfOpcode = FALSE;\r
1970 ScopeCount = 0;\r
1971 pSNode = pQuestionNode;\r
1972\r
1973 //\r
1974 // Parse all the opcodes in the Question.\r
1975 //\r
1976 while (pSNode != NULL) {\r
1977 pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1978 //\r
1979 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.\r
1980 // Scopes may be nested within other scopes.\r
1981 // When finishing parsing a question, the scope count must be zero.\r
1982 //\r
1983 if (pSOpHead->Scope == 1) {\r
1984 ScopeCount++;\r
1985 }\r
1986 if (pSOpHead->OpCode == EFI_IFR_END_OP) {\r
1987 ScopeCount--;\r
1988 }\r
1989 //\r
1990 // Check whether finishing parsing a question.\r
1991 //\r
1992 if (ScopeCount == 0) {\r
1993 break;\r
1994 }\r
1995\r
1996 //\r
1997 // Record the default information in the question.\r
1998 //\r
1999 switch (pSOpHead->OpCode) {\r
2000 case EFI_IFR_ONE_OF_OP:\r
2001 IsOneOfOpcode = TRUE;\r
2002 break;\r
2003 case EFI_IFR_CHECKBOX_OP:\r
2004 //\r
2005 // The default info of check box may be given by flag.\r
2006 // So need to check the flag of check box.\r
2007 //\r
2008 CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;\r
2009 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {\r
2010 //\r
2011 // Check whether need to update the smallest default id.\r
2012 //\r
2013 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
2014 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
2015 }\r
2016 //\r
2017 // Update the QuestionDefaultInfo.\r
2018 //\r
2019 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2020 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
2021 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2022 QuestionDefaultInfo->mDefaultNumber ++;\r
2023 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2024 }\r
2025 break;\r
2026 }\r
2027 }\r
2028 }\r
2029 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {\r
2030 //\r
2031 // Check whether need to update the smallest default id.\r
2032 //\r
2033 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2034 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
2035 }\r
2036 //\r
2037 // Update the QuestionDefaultInfo.\r
2038 //\r
2039 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2040 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2041 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2042 QuestionDefaultInfo->mDefaultNumber ++;\r
2043 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2044 }\r
2045 break;\r
2046 }\r
2047 }\r
2048 }\r
2049 break;\r
2050 case EFI_IFR_ONE_OF_OPTION_OP:\r
2051 if (!IsOneOfOpcode) {\r
2052 //\r
2053 // Only check the option in oneof.\r
2054 //\r
2055 break;\r
2056 }\r
2057 OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;\r
2058 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
2059 //\r
2060 // The option is used as the standard default.\r
2061 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2062 //\r
2063 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
2064 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
2065 QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
2066 }\r
2067 //\r
2068 // Update the IsDefaultIdExist array in QuestionDefaultInfo.\r
2069 //\r
2070 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2071 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
2072 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2073 QuestionDefaultInfo->mDefaultNumber ++;\r
2074 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2075 }\r
2076 break;\r
2077 }\r
2078 }\r
2079 }\r
2080 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {\r
2081 //\r
2082 // This option is used as the manufacture default.\r
2083 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2084 //\r
2085 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2086 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
2087 QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
2088 }\r
2089 //\r
2090 // Update the QuestionDefaultInfo.\r
2091 //\r
2092 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2093 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2094 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2095 QuestionDefaultInfo->mDefaultNumber ++;\r
2096 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2097 }\r
2098 break;\r
2099 }\r
2100 }\r
2101 }\r
2102 break;\r
2103 case EFI_IFR_DEFAULT_OP:\r
2104 DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;\r
2105 //\r
2106 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2107 //\r
2108 if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {\r
2109 SmallestDefaultId = DefaultOpcode->DefaultId;\r
2110 QuestionDefaultInfo->mDefaultValueRecord= pSNode;\r
2111 QuestionDefaultInfo->mIsDefaultOpcode= TRUE;\r
2112 }\r
2113 //\r
2114 // Update the QuestionDefaultInfo.\r
2115 //\r
2116 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){\r
2117 if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {\r
2118 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2119 QuestionDefaultInfo->mDefaultNumber ++;\r
2120 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2121 }\r
2122 break;\r
2123 }\r
2124 }\r
2125 break;\r
2126 default:\r
2127 break;\r
2128 }\r
2129 //\r
2130 // Parse next opcode in this question.\r
2131 //\r
2132 pSNode = pSNode->mNext;\r
2133 }\r
2134}\r
2135\r
2136/**\r
2137 Check or add default for question if need.\r
2138\r
2139 This function will check the default info for question.\r
2140 If the question has default, but the default number < defaultstore opcode number.\r
2141 will do following two action :\r
2142\r
2143 1. if (AutoDefault) will add default for question to support all kinds of defaults.\r
2144 2. if (CheckDefault) will generate an error to tell user the question misses some default value.\r
2145\r
2146 We assume that the two options can not be TRUE at same time.\r
2147 If they are TRUE at same time, only do the action corresponding to AutoDefault option.\r
2148\r
2149 @param AutoDefault Add default for question if needed\r
2150 @param CheckDefault Check the default info, if missing default, generates an error.\r
2151\r
2152**/\r
2153VOID\r
2154CIfrRecordInfoDB::IfrCheckAddDefaultRecord (\r
2155 BOOLEAN AutoDefault,\r
2156 BOOLEAN CheckDefault\r
2157 )\r
2158{\r
2159 SIfrRecord *pNode;\r
2160 SIfrRecord *pTailNode;\r
2161 SIfrRecord *pStartAdjustNode;\r
2162 EFI_IFR_OP_HEADER *pOpHead;\r
2163 QuestionDefaultRecord QuestionDefaultInfo;\r
2164 UINT8 MissingDefaultCount;\r
2165 CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
2166\r
2167 pNode = mIfrRecordListHead;\r
2168\r
2169 //\r
2170 // Record the number and default id of all defaultstore opcode.\r
2171 //\r
2172 IfrGetDefaultStoreInfo ();\r
2173\r
2174 while (pNode != NULL) {\r
2175 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
2176 //\r
2177 // Check whether is question opcode.\r
2178 //\r
2179 if (CheckQuestionOpCode (pOpHead->OpCode)) {\r
2180 //\r
2181 // Initialize some local variables here, because they vary with question.\r
2182 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.\r
2183 //\r
2184 memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));\r
2185 pTailNode = mIfrRecordListTail;\r
2186 //\r
2187 // Get the QuestionDefaultInfo for current question.\r
2188 //\r
2189 IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);\r
2190\r
2191 if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {\r
2192 if (AutoDefault) {\r
2193 //\r
2194 // Create default for question which misses default.\r
2195 //\r
2196 IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);\r
2197\r
2198 //\r
2199 // Adjust the buffer content.\r
2200 // pStartAdjustNode->mIfrBinBuf points to the insert position.\r
2201 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.\r
2202 //\r
2203 pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);\r
2204 gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);\r
2205\r
2206 //\r
2207 // Update the record info.\r
2208 //\r
2209 IfrUpdateRecordInfoForDynamicOpcode (TRUE);\r
2210 } else if (CheckDefault) {\r
2211 //\r
2212 // Generate an error for question which misses default.\r
2213 //\r
2214 MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;\r
2215 sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);\r
2216 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);\r
2217 }\r
2218 }\r
2219 }\r
2220 //\r
2221 // parse next opcode.\r
2222 //\r
2223 pNode = pNode->mNext;\r
2224 }\r
2225}\r
2226\r
30fdf114
LG
2227CIfrRecordInfoDB gCIfrRecordInfoDB;\r
2228\r
2229VOID\r
2230CIfrObj::_EMIT_PENDING_OBJ (\r
2231 VOID\r
2232 )\r
2233{\r
2234 CHAR8 *ObjBinBuf = NULL;\r
f7496d71 2235\r
30fdf114
LG
2236 //\r
2237 // do nothing\r
2238 //\r
2239 if (!mDelayEmit || !gCreateOp) {\r
2240 return;\r
2241 }\r
2242\r
2243 mPkgOffset = gCFormPkg.GetPkgLength ();\r
2244 //\r
2245 // update data buffer to package data\r
2246 //\r
2247 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
2248 if (ObjBinBuf != NULL) {\r
f51461c8 2249 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
30fdf114 2250 }\r
f7496d71 2251\r
30fdf114
LG
2252 //\r
2253 // update bin buffer to package data buffer\r
2254 //\r
2255 if (mObjBinBuf != NULL) {\r
f7e98581 2256 delete[] mObjBinBuf;\r
30fdf114
LG
2257 mObjBinBuf = ObjBinBuf;\r
2258 }\r
f7496d71 2259\r
30fdf114
LG
2260 mDelayEmit = FALSE;\r
2261}\r
2262\r
2263/*\r
2264 * The definition of CIfrObj's member function\r
2265 */\r
2266static struct {\r
2267 UINT8 mSize;\r
2268 UINT8 mScope;\r
2269} gOpcodeSizesScopeTable[] = {\r
2270 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
2271 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
2272 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
2273 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
2274 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
2275 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
2276 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
2277 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
2278 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
2279 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
2280 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
2281 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
2282 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
2283 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
2284 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
2285 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
2286 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
2287 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
2288 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
2289 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
b303ea72 2290 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
2291 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
2292 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
2293 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
2294 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
2295 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
2296 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
2297 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
2298 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
2299 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
2300 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
2301 { 0, 0 }, // 0x1F\r
2302 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
2303 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
52302d4d 2304 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
2305 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
2306 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
2307 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
2308 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
2309 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
2310 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
2311 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
52302d4d
LG
2312 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
2313 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
2314 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
2315 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
2316 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
30fdf114
LG
2317 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
2318 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
2319 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
2320 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
2321 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
2322 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
2323 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
2324 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
2325 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
2326 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
2327 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
2328 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
2329 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
2330 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
2331 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
2332 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
2333 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
2334 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
2335 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
2336 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
2337 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
2338 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
2339 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
2340 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
2341 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
2342 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
2343 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
2344 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
2345 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
2346 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
2347 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
2348 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
2349 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
2350 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
2351 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
2352 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
2353 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
2354 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
2355 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
2356 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
2357 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
2358 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
2359 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
2360 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
2361 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
2362 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
52302d4d 2363 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
2364 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
2365 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 2366 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
4afd3d04 2367 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
4234283c 2368 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
ea0f6464 2369 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
5d377616 2370 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64\r
30fdf114
LG
2371};\r
2372\r
2373#ifdef CIFROBJ_DEUBG\r
2374static struct {\r
2375 CHAR8 *mIfrName;\r
2376} gIfrObjPrintDebugTable[] = {\r
2377 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
2378 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
2379 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
2380 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",\r
2381 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
52302d4d 2382 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 2383 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 2384 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
2385 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",\r
2386 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
2387 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
2388 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
2389 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
2390 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
2391 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
52302d4d 2392 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
5d377616 2393 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",\r
30fdf114
LG
2394};\r
2395\r
2396VOID\r
2397CIFROBJ_DEBUG_PRINT (\r
2398 IN UINT8 OpCode\r
2399 )\r
2400{\r
2401 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
2402}\r
2403#else\r
2404\r
2405#define CIFROBJ_DEBUG_PRINT(OpCode)\r
2406\r
2407#endif\r
2408\r
52302d4d 2409BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
2410\r
2411CIfrObj::CIfrObj (\r
2412 IN UINT8 OpCode,\r
2413 OUT CHAR8 **IfrObj,\r
2414 IN UINT8 ObjBinLen,\r
2415 IN BOOLEAN DelayEmit\r
2416 )\r
2417{\r
2418 mDelayEmit = DelayEmit;\r
2419 mPkgOffset = gCFormPkg.GetPkgLength ();\r
2420 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
2421 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
2422 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
b748e35c 2423 mLineNo = 0;\r
30fdf114 2424\r
9b78c54a
HW
2425 assert (mObjBinBuf != NULL);\r
2426\r
30fdf114
LG
2427 if (IfrObj != NULL) {\r
2428 *IfrObj = mObjBinBuf;\r
2429 }\r
2430\r
2431 CIFROBJ_DEBUG_PRINT (OpCode);\r
2432}\r
2433\r
2434CIfrObj::~CIfrObj (\r
2435 VOID\r
2436 )\r
2437{\r
2438 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
2439 _EMIT_PENDING_OBJ ();\r
2440 }\r
2441\r
2442 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
2443}\r
2444\r
2445/*\r
2446 * The definition of CIfrObj's member function\r
2447 */\r
2448UINT8 gScopeCount = 0;\r
2449\r
2450CIfrOpHeader::CIfrOpHeader (\r
2451 IN UINT8 OpCode,\r
2452 IN VOID *StartAddr,\r
2453 IN UINT8 Length\r
2454 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
2455{\r
2456 mHeader->OpCode = OpCode;\r
2457 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
2458 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
2459}\r
2460\r
2461CIfrOpHeader::CIfrOpHeader (\r
2462 IN CIfrOpHeader &OpHdr\r
2463 )\r
2464{\r
2465 mHeader = OpHdr.mHeader;\r
2466}\r
2467\r
52302d4d 2468UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r