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