]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools/VfrCompile: Remove unused local variables
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 The definition of CFormPkg's member function\r
4\r
bec3a181 5Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
9b78c54a 17#include "assert.h"\r
30fdf114
LG
18#include "VfrFormPkg.h"\r
19\r
20/*\r
21 * The definition of CFormPkg's member function\r
22 */\r
23\r
24SPendingAssign::SPendingAssign (\r
25 IN CHAR8 *Key, \r
26 IN VOID *Addr, \r
27 IN UINT32 Len, \r
28 IN UINT32 LineNo,\r
52302d4d 29 IN CONST CHAR8 *Msg\r
30fdf114
LG
30 )\r
31{\r
32 mKey = NULL;\r
33 mAddr = Addr;\r
34 mLen = Len;\r
35 mFlag = PENDING;\r
36 mLineNo = LineNo;\r
37 mMsg = NULL;\r
38 mNext = NULL;\r
39 if (Key != NULL) {\r
40 mKey = new CHAR8[strlen (Key) + 1];\r
41 if (mKey != NULL) {\r
42 strcpy (mKey, Key);\r
43 }\r
44 }\r
45\r
46 if (Msg != NULL) {\r
47 mMsg = new CHAR8[strlen (Msg) + 1];\r
48 if (mMsg != NULL) {\r
49 strcpy (mMsg, Msg);\r
50 }\r
51 }\r
52}\r
53\r
54SPendingAssign::~SPendingAssign (\r
55 VOID\r
56 )\r
57{\r
58 if (mKey != NULL) {\r
fd542523 59 delete[] mKey;\r
30fdf114
LG
60 }\r
61 mAddr = NULL;\r
62 mLen = 0;\r
63 mLineNo = 0;\r
64 if (mMsg != NULL) {\r
fd542523 65 delete[] mMsg;\r
30fdf114
LG
66 }\r
67 mNext = NULL;\r
68}\r
69\r
70VOID\r
71SPendingAssign::SetAddrAndLen (\r
72 IN VOID *Addr, \r
73 IN UINT32 LineNo\r
74 )\r
75{\r
76 mAddr = Addr;\r
77 mLineNo = LineNo;\r
78}\r
79\r
80VOID\r
81SPendingAssign::AssignValue (\r
82 IN VOID *Addr, \r
83 IN UINT32 Len\r
84 )\r
85{\r
f51461c8 86 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));\r
30fdf114
LG
87 mFlag = ASSIGNED;\r
88}\r
89\r
90CHAR8 *\r
91SPendingAssign::GetKey (\r
92 VOID\r
93 )\r
94{\r
95 return mKey;\r
96}\r
97\r
98CFormPkg::CFormPkg (\r
ed395cfe 99 IN UINT32 BufferSize\r
30fdf114
LG
100 )\r
101{\r
102 CHAR8 *BufferStart;\r
103 CHAR8 *BufferEnd;\r
104 SBufferNode *Node;\r
105\r
106 mPkgLength = 0;\r
107 mBufferNodeQueueHead = NULL;\r
108 mCurrBufferNode = NULL;\r
109\r
110 Node = new SBufferNode;\r
111 if (Node == NULL) {\r
112 return ;\r
113 }\r
114 BufferStart = new CHAR8[BufferSize];\r
115 if (BufferStart == NULL) {\r
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
141 delete pBNode->mBufferStart;\r
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
252 IN CHAR8 *Buffer, \r
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
306 \r
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
354 \r
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
LG
423\r
424EFI_VFR_RETURN_CODE \r
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
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
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
468 \r
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
500 IN CHAR8 *Key, \r
501 IN VOID *ValAddr, \r
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
521 IN CHAR8 *Key, \r
522 IN VOID *ValAddr, \r
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
831\r
b36d134f
LG
832 //\r
833 // Declare all questions as Numeric in DisableIf True\r
834 //\r
835 // DisableIf\r
836 CIfrDisableIf DIObj;\r
837 DIObj.SetLineNo (LineNo);\r
4afd3d04 838 *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
b36d134f
LG
839 \r
840 //TrueOpcode\r
841 CIfrTrue TObj (LineNo);\r
842\r
843 // Declare Numeric qeustion for each undefined question.\r
30fdf114
LG
844 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
845 if (pNode->mFlag == PENDING) {\r
30fdf114
LG
846 CIfrNumeric CNObj;\r
847 EFI_VARSTORE_INFO Info; \r
4afd3d04 848 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
30fdf114
LG
849\r
850 CNObj.SetLineNo (LineNo);\r
851 CNObj.SetPrompt (0x0);\r
852 CNObj.SetHelp (0x0);\r
853\r
854 //\r
855 // Register this question, assume it is normal question, not date or time question\r
856 //\r
857 VarStr = pNode->mKey;\r
858 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);\r
859 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
860 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
861 return ReturnCode;\r
862 }\r
863 \r
864#ifdef VFREXP_DEBUG\r
865 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
866#endif\r
867 //\r
868 // Get Question Info, framework vfr VarName == StructName\r
869 //\r
870 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);\r
871 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
872 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");\r
873 return ReturnCode;\r
874 }\r
875 //\r
876 // Get VarStoreType\r
877 //\r
4afd3d04 878 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
30fdf114
LG
879 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
880 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
881 return ReturnCode;\r
882 }\r
4afd3d04 883 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
30fdf114
LG
884\r
885 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
886 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
887 } else {\r
888 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
889 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
890 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
891 VarStr = pNode->mKey;\r
b36d134f 892 //convert VarStr with store name to VarStr with structure name\r
4afd3d04 893 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
b36d134f
LG
894 if (ReturnCode == VFR_RETURN_SUCCESS) {\r
895 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
896 NewStr[0] = '\0';\r
897 strcpy (NewStr, SName);\r
898 strcat (NewStr, VarStr + strlen (FName));\r
899 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
fd542523 900 delete[] NewStr;\r
b36d134f 901 }\r
30fdf114
LG
902 } else {\r
903 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
904 }\r
905 }\r
906 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
907 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
908 return ReturnCode;\r
909 }\r
910\r
911 CNObj.SetQuestionId (QId);\r
912 CNObj.SetVarStoreInfo (&Info);\r
0d2711a6
LG
913 //\r
914 // Numeric doesn't support BOOLEAN data type. \r
915 // BOOLEAN type has the same data size to UINT8. \r
916 //\r
917 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
918 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
919 }\r
30fdf114 920 CNObj.SetFlags (0, Info.mVarType);\r
2bcc713e
LG
921 //\r
922 // Use maximum value not to limit the vaild value for the undefined question.\r
923 //\r
924 switch (Info.mVarType) {\r
925 case EFI_IFR_TYPE_NUM_SIZE_64:\r
926 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
4afd3d04 927 ShrinkSize = 0;\r
2bcc713e
LG
928 break;\r
929 case EFI_IFR_TYPE_NUM_SIZE_32:\r
930 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
4afd3d04 931 ShrinkSize = 12;\r
2bcc713e
LG
932 break;\r
933 case EFI_IFR_TYPE_NUM_SIZE_16:\r
934 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
4afd3d04 935 ShrinkSize = 18;\r
2bcc713e
LG
936 break;\r
937 case EFI_IFR_TYPE_NUM_SIZE_8:\r
938 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
4afd3d04 939 ShrinkSize = 21;\r
2bcc713e
LG
940 break;\r
941 default:\r
942 break;\r
943 }\r
4afd3d04 944 CNObj.ShrinkBinSize (ShrinkSize);\r
30fdf114
LG
945\r
946 //\r
947 // For undefined Efi VarStore type question\r
948 // Append the extended guided opcode to contain VarName\r
949 //\r
b36d134f 950 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
30fdf114
LG
951 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
952 CVNObj.SetLineNo (LineNo);\r
953 }\r
4afd3d04 954\r
30fdf114
LG
955 //\r
956 // End for Numeric\r
957 //\r
958 CIfrEnd CEObj; \r
959 CEObj.SetLineNo (LineNo);\r
30fdf114
LG
960 }\r
961 }\r
b36d134f
LG
962\r
963 //\r
964 // End for DisableIf\r
965 //\r
966 CIfrEnd SEObj;\r
967 SEObj.SetLineNo (LineNo);\r
968\r
30fdf114
LG
969 return VFR_RETURN_SUCCESS;\r
970}\r
971\r
972CFormPkg gCFormPkg;\r
973\r
974SIfrRecord::SIfrRecord (\r
975 VOID\r
976 )\r
977{\r
978 mIfrBinBuf = NULL;\r
979 mBinBufLen = 0;\r
980 mLineNo = 0xFFFFFFFF;\r
981 mOffset = 0xFFFFFFFF;\r
982 mNext = NULL;\r
983}\r
984\r
985SIfrRecord::~SIfrRecord (\r
986 VOID\r
987 )\r
988{\r
989 if (mIfrBinBuf != NULL) {\r
990 //delete mIfrBinBuf;\r
991 mIfrBinBuf = NULL;\r
992 }\r
993 mLineNo = 0xFFFFFFFF;\r
994 mOffset = 0xFFFFFFFF;\r
995 mBinBufLen = 0;\r
996 mNext = NULL;\r
997}\r
998\r
999CIfrRecordInfoDB::CIfrRecordInfoDB (\r
1000 VOID\r
1001 )\r
1002{\r
1003 mSwitch = TRUE;\r
1004 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
1005 mIfrRecordListHead = NULL;\r
1006 mIfrRecordListTail = NULL;\r
74bbe31b
DB
1007 mAllDefaultTypeCount = 0;\r
1008 for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {\r
1009 mAllDefaultIdArray[i] = 0xffff;\r
1010 }\r
30fdf114
LG
1011}\r
1012\r
1013CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
1014 VOID\r
1015 )\r
1016{\r
1017 SIfrRecord *pNode;\r
1018\r
1019 while (mIfrRecordListHead != NULL) {\r
1020 pNode = mIfrRecordListHead;\r
1021 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
1022 delete pNode;\r
1023 }\r
1024}\r
1025\r
1026SIfrRecord *\r
1027CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
1028 IN UINT32 RecordIdx\r
1029 )\r
1030{\r
1031 UINT32 Idx;\r
1032 SIfrRecord *pNode = NULL;\r
1033\r
1034 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
1035 return NULL;\r
1036 }\r
1037\r
1038 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
1039 (Idx != RecordIdx) && (pNode != NULL);\r
1040 Idx++, pNode = pNode->mNext)\r
1041 ;\r
1042\r
1043 return pNode;\r
1044}\r
1045\r
1046UINT32\r
1047CIfrRecordInfoDB::IfrRecordRegister (\r
1048 IN UINT32 LineNo,\r
1049 IN CHAR8 *IfrBinBuf,\r
1050 IN UINT8 BinBufLen,\r
1051 IN UINT32 Offset\r
1052 )\r
1053{\r
1054 SIfrRecord *pNew;\r
1055\r
1056 if (mSwitch == FALSE) {\r
1057 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1058 }\r
1059\r
1060 if ((pNew = new SIfrRecord) == NULL) {\r
1061 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1062 }\r
1063\r
1064 if (mIfrRecordListHead == NULL) {\r
1065 mIfrRecordListHead = pNew;\r
1066 mIfrRecordListTail = pNew;\r
1067 } else {\r
1068 mIfrRecordListTail->mNext = pNew;\r
1069 mIfrRecordListTail = pNew;\r
1070 }\r
1071 mRecordCount++;\r
1072\r
1073 return mRecordCount;\r
1074}\r
1075\r
1076VOID\r
1077CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
1078 IN UINT32 RecordIdx,\r
1079 IN UINT32 LineNo,\r
1080 IN CHAR8 *BinBuf,\r
1081 IN UINT8 BinBufLen,\r
1082 IN UINT32 Offset\r
1083 )\r
1084{\r
1085 SIfrRecord *pNode;\r
fd171542 1086 SIfrRecord *Prev;\r
30fdf114
LG
1087\r
1088 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
1089 return;\r
1090 }\r
1091\r
fd171542 1092 if (LineNo == 0) {\r
1093 //\r
1094 // Line number is not specified explicitly, try to use line number of previous opcode\r
1095 //\r
1096 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
1097 if (Prev != NULL) {\r
1098 LineNo = Prev->mLineNo;\r
1099 }\r
1100 }\r
1101\r
30fdf114
LG
1102 pNode->mLineNo = LineNo;\r
1103 pNode->mOffset = Offset;\r
1104 pNode->mBinBufLen = BinBufLen;\r
1105 pNode->mIfrBinBuf = BinBuf;\r
1106\r
1107}\r
1108\r
1109VOID\r
1110CIfrRecordInfoDB::IfrRecordOutput (\r
1111 OUT PACKAGE_DATA &TBuffer\r
1112 )\r
1113{\r
1114 CHAR8 *Temp;\r
1115 SIfrRecord *pNode; \r
1116\r
1117 if (TBuffer.Buffer != NULL) {\r
1118 delete TBuffer.Buffer;\r
1119 }\r
1120\r
1121 TBuffer.Size = 0;\r
1122 TBuffer.Buffer = NULL;\r
1123\r
1124\r
1125 if (mSwitch == FALSE) {\r
1126 return;\r
1127 } \r
1128 \r
1129 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1130 TBuffer.Size += pNode->mBinBufLen;\r
1131 }\r
1132 \r
1133 if (TBuffer.Size != 0) {\r
1134 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
1135 } else {\r
1136 return;\r
1137 }\r
1138 \r
1139 Temp = TBuffer.Buffer;\r
1140\r
1141 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1142 if (pNode->mIfrBinBuf != NULL) {\r
1143 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
1144 Temp += pNode->mBinBufLen;\r
1145 }\r
1146 }\r
1147\r
1148 return; \r
1149} \r
1150\r
1151VOID\r
1152CIfrRecordInfoDB::IfrRecordOutput (\r
1153 IN FILE *File,\r
1154 IN UINT32 LineNo\r
1155 )\r
1156{\r
1157 SIfrRecord *pNode;\r
1158 UINT8 Index;\r
1159 UINT32 TotalSize;\r
1160\r
1161 if (mSwitch == FALSE) {\r
1162 return;\r
1163 }\r
1164\r
1165 if (File == NULL) {\r
1166 return;\r
1167 }\r
1168\r
1169 TotalSize = 0;\r
1170\r
1171 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1172 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
1173 fprintf (File, ">%08X: ", pNode->mOffset);\r
1174 TotalSize += pNode->mBinBufLen;\r
1175 if (pNode->mIfrBinBuf != NULL) {\r
1176 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
1177 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
1178 }\r
1179 }\r
1180 fprintf (File, "\n");\r
1181 }\r
1182 }\r
1183 \r
1184 if (LineNo == 0) {\r
1185 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
1186 }\r
1187}\r
1188\r
1189//\r
1190// for framework vfr file\r
1191// adjust opcode sequence for uefi IFR format\r
1192// adjust inconsistent and varstore into the right position.\r
1193//\r
1194BOOLEAN\r
1195CIfrRecordInfoDB::CheckQuestionOpCode (\r
1196 IN UINT8 OpCode\r
1197 )\r
1198{\r
1199 switch (OpCode) {\r
1200 case EFI_IFR_CHECKBOX_OP:\r
1201 case EFI_IFR_NUMERIC_OP:\r
1202 case EFI_IFR_PASSWORD_OP:\r
1203 case EFI_IFR_ONE_OF_OP:\r
1204 case EFI_IFR_ACTION_OP:\r
1205 case EFI_IFR_STRING_OP:\r
1206 case EFI_IFR_DATE_OP:\r
1207 case EFI_IFR_TIME_OP:\r
1208 case EFI_IFR_ORDERED_LIST_OP:\r
bec3a181 1209 case EFI_IFR_REF_OP:\r
30fdf114
LG
1210 return TRUE;\r
1211 default:\r
1212 return FALSE;\r
1213 }\r
1214}\r
1215\r
1216BOOLEAN\r
1217CIfrRecordInfoDB::CheckIdOpCode (\r
1218 IN UINT8 OpCode\r
1219 )\r
1220{\r
1221 switch (OpCode) {\r
1222 case EFI_IFR_EQ_ID_VAL_OP:\r
1223 case EFI_IFR_EQ_ID_ID_OP:\r
64b2609f 1224 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
30fdf114
LG
1225 case EFI_IFR_QUESTION_REF1_OP:\r
1226 return TRUE;\r
1227 default:\r
1228 return FALSE;\r
1229 }\r
1230} \r
1231\r
1232EFI_QUESTION_ID\r
1233CIfrRecordInfoDB::GetOpcodeQuestionId (\r
1234 IN EFI_IFR_OP_HEADER *OpHead\r
1235 )\r
1236{\r
1237 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1238 \r
1239 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
1240 \r
1241 return QuestionHead->QuestionId;\r
1242}\r
1243\r
4afd3d04
LG
1244SIfrRecord *\r
1245CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
1246 IN UINT32 Offset\r
1247 )\r
1248{\r
1249 SIfrRecord *pNode = NULL;\r
1250\r
1251 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1252 if (pNode->mOffset == Offset) {\r
1253 return pNode;\r
1254 }\r
1255 }\r
1256\r
1257 return pNode;\r
1258}\r
1259\r
74bbe31b 1260/**\r
4afd3d04
LG
1261 Add just the op code position.\r
1262\r
74bbe31b
DB
1263 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,\r
1264 so pDynamicOpcodeNodes is before mIfrRecordListTail.\r
1265\r
4afd3d04 1266 From\r
74bbe31b
DB
1267\r
1268 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|\r
1269\r
4afd3d04 1270 To\r
4afd3d04 1271\r
74bbe31b
DB
1272 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|\r
1273\r
1274 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,\r
1275 so new records are appennded to the end of OriginalIfrRecordListTail.\r
1276\r
1277 From\r
1278\r
1279 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|\r
1280\r
1281 To\r
1282\r
1283 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|\r
1284\r
1285\r
1286 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
1287\r
1288**/\r
4afd3d04
LG
1289BOOLEAN\r
1290CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
74bbe31b 1291 IN BOOLEAN CreateOpcodeAfterParsingVfr\r
4afd3d04
LG
1292 )\r
1293{\r
1294 UINT32 OpcodeOffset;\r
1295 SIfrRecord *pNode, *pPreNode;\r
74bbe31b
DB
1296 SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;\r
1297 SIfrRecord *pNodeBeforeDynamic;\r
1298\r
61eb9834 1299 pPreNode = NULL;\r
74bbe31b
DB
1300 pAdjustNode = NULL;\r
1301 pNodeBeforeDynamic = NULL;\r
1302 OpcodeOffset = 0;\r
4afd3d04
LG
1303\r
1304 //\r
74bbe31b
DB
1305 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,\r
1306 // and the node before pDynamicOpcodeNode.\r
4afd3d04 1307 //\r
74bbe31b 1308 for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {\r
4afd3d04 1309 if (OpcodeOffset == gAdjustOpcodeOffset) {\r
74bbe31b
DB
1310 pAdjustNode = pNode;\r
1311 pNodeBeforeAdjust = pPreNode;\r
4afd3d04 1312 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
74bbe31b
DB
1313 pNodeBeforeDynamic = pPreNode;\r
1314 }\r
1315 if (pNode->mNext != NULL) {\r
1316 pPreNode = pNode;\r
4afd3d04 1317 }\r
4afd3d04
LG
1318 OpcodeOffset += pNode->mBinBufLen;\r
1319 }\r
1320\r
1321 //\r
74bbe31b 1322 // Check the nodes whether exist.\r
4afd3d04 1323 //\r
9b78c54a 1324 if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {\r
4afd3d04
LG
1325 return FALSE;\r
1326 }\r
1327\r
1328 //\r
1329 // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
1330 //\r
74bbe31b
DB
1331 pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;\r
1332 if (CreateOpcodeAfterParsingVfr) {\r
1333 //\r
1334 // mIfrRecordListTail is the end of pDynamicNode (Case2).\r
1335 //\r
1336 mIfrRecordListTail->mNext = pAdjustNode;\r
1337 mIfrRecordListTail = pNodeBeforeDynamic;\r
1338 mIfrRecordListTail->mNext = NULL;\r
1339 } else {\r
1340 //\r
1341 //pPreNode is the end of pDynamicNode(Case1).\r
1342 //\r
1343 pPreNode->mNext = pAdjustNode;\r
1344 pNodeBeforeDynamic->mNext = mIfrRecordListTail;\r
1345 }\r
4afd3d04
LG
1346\r
1347 return TRUE;\r
1348}\r
1349\r
74bbe31b
DB
1350/**\r
1351 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.\r
1352\r
1353 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
1354\r
1355**/\r
1356VOID\r
1357CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (\r
1358 IN BOOLEAN CreateOpcodeAfterParsingVfr\r
1359 )\r
1360{\r
1361 SIfrRecord *pRecord;\r
1362\r
1363 //\r
1364 // Base on the original offset info to update the record list.\r
1365 //\r
1366 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {\r
1367 gCVfrErrorHandle.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");\r
1368 }\r
1369\r
1370 //\r
1371 // Base on the opcode binary length to recalculate the offset for each opcode.\r
1372 //\r
1373 IfrAdjustOffsetForRecord();\r
1374\r
1375 //\r
1376 // Base on the offset to find the binary address.\r
1377 //\r
1378 pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);\r
1379 while (pRecord != NULL) {\r
1380 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);\r
1381 pRecord = pRecord->mNext;\r
1382 }\r
1383}\r
1384\r
1385\r
4afd3d04
LG
1386VOID\r
1387CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
1388 VOID\r
1389 )\r
1390{\r
1391 UINT32 OpcodeOffset;\r
1392 SIfrRecord *pNode;\r
1393\r
1394 OpcodeOffset = 0;\r
1395 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1396 pNode->mOffset = OpcodeOffset;\r
1397 OpcodeOffset += pNode->mBinBufLen;\r
1398 }\r
1399}\r
1400\r
30fdf114
LG
1401EFI_VFR_RETURN_CODE\r
1402CIfrRecordInfoDB::IfrRecordAdjust (\r
1403 VOID\r
1404 )\r
1405{\r
1406 SIfrRecord *pNode, *preNode;\r
1407 SIfrRecord *uNode, *tNode;\r
1408 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
1409 EFI_QUESTION_ID QuestionId;\r
1410 UINT32 StackCount;\r
1411 UINT32 QuestionScope;\r
30fdf114
LG
1412 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
1413 EFI_VFR_RETURN_CODE Status;\r
1414\r
1415 //\r
1416 // Init local variable\r
1417 //\r
1418 Status = VFR_RETURN_SUCCESS;\r
1419 pNode = mIfrRecordListHead;\r
1420 preNode = pNode;\r
1421 QuestionScope = 0;\r
1422 while (pNode != NULL) {\r
1423 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1424 \r
1425 //\r
1426 // make sure the inconsistent opcode in question scope\r
1427 //\r
1428 if (QuestionScope > 0) {\r
1429 QuestionScope += OpHead->Scope;\r
1430 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1431 QuestionScope --;\r
1432 }\r
1433 }\r
1434 \r
1435 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1436 QuestionScope = 1;\r
1437 }\r
1438 //\r
1439 // for the inconsistent opcode not in question scope, adjust it\r
1440 //\r
1441 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1442 //\r
1443 // for inconsistent opcode not in question scope\r
1444 //\r
1445\r
1446 //\r
1447 // Count inconsistent opcode Scope \r
1448 //\r
1449 StackCount = OpHead->Scope;\r
1450 QuestionId = EFI_QUESTION_ID_INVALID;\r
1451 tNode = pNode;\r
1452 while (tNode != NULL && StackCount > 0) {\r
1453 tNode = tNode->mNext;\r
1454 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1455 //\r
1456 // Calculate Scope Number\r
1457 //\r
1458 StackCount += tOpHead->Scope;\r
1459 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1460 StackCount --;\r
1461 }\r
1462 //\r
1463 // by IdEqual opcode to get QuestionId\r
1464 //\r
1465 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1466 CheckIdOpCode (tOpHead->OpCode)) {\r
1467 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1468 }\r
1469 }\r
1470 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1471 //\r
1472 // report error; not found\r
1473 //\r
1474 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1475 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1476 Status = VFR_RETURN_MISMATCHED;\r
1477 break;\r
1478 }\r
1479 //\r
1480 // extract inconsistent opcode list\r
1481 // pNode is Incosistent opcode, tNode is End Opcode\r
1482 //\r
1483 \r
1484 //\r
1485 // insert inconsistent opcode list into the right question scope by questionid\r
1486 //\r
1487 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1488 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1489 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1490 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1491 break;\r
1492 }\r
1493 }\r
1494 //\r
1495 // insert inconsistent opcode list and check LATE_CHECK flag\r
1496 //\r
1497 if (uNode != NULL) {\r
1498 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1499 //\r
1500 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1501 //\r
1502 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1503 }\r
1504 \r
1505 //\r
1506 // skip the default storage for Date and Time\r
1507 //\r
1508 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1509 uNode = uNode->mNext;\r
1510 }\r
1511\r
1512 preNode->mNext = tNode->mNext;\r
1513 tNode->mNext = uNode->mNext;\r
1514 uNode->mNext = pNode;\r
1515 //\r
1516 // reset pNode to head list, scan the whole list again.\r
1517 //\r
1518 pNode = mIfrRecordListHead;\r
1519 preNode = pNode;\r
1520 QuestionScope = 0;\r
1521 continue;\r
1522 } else {\r
1523 //\r
1524 // not found matched question id, report error\r
1525 //\r
1526 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1527 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1528 Status = VFR_RETURN_MISMATCHED;\r
1529 break;\r
1530 }\r
1531 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1532 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1533 //\r
1534 // for new added group of varstore opcode\r
1535 //\r
1536 tNode = pNode;\r
1537 while (tNode->mNext != NULL) {\r
1538 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1539 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1540 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1541 break; \r
1542 }\r
1543 tNode = tNode->mNext;\r
1544 }\r
1545\r
1546 if (tNode->mNext == NULL) {\r
1547 //\r
1548 // invalid IfrCode, IfrCode end by EndOpCode\r
1549 // \r
1550 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1551 Status = VFR_RETURN_MISMATCHED;\r
1552 break;\r
1553 }\r
1554 \r
1555 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1556 //\r
1557 // not new added varstore, which are not needed to be adjust.\r
1558 //\r
1559 preNode = tNode;\r
1560 pNode = tNode->mNext;\r
1561 continue; \r
1562 } else {\r
1563 //\r
1564 // move new added varstore opcode to the position befor form opcode \r
1565 // varstore opcode between pNode and tNode\r
1566 //\r
1567\r
1568 //\r
1569 // search form opcode from begin\r
1570 //\r
1571 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1572 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1573 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1574 break;\r
1575 }\r
1576 }\r
1577 //\r
1578 // Insert varstore opcode beform form opcode if form opcode is found\r
1579 //\r
1580 if (uNode->mNext != NULL) {\r
1581 preNode->mNext = tNode->mNext;\r
1582 tNode->mNext = uNode->mNext;\r
1583 uNode->mNext = pNode;\r
1584 //\r
1585 // reset pNode to head list, scan the whole list again.\r
1586 //\r
1587 pNode = mIfrRecordListHead;\r
1588 preNode = pNode;\r
1589 QuestionScope = 0;\r
1590 continue;\r
1591 } else {\r
1592 //\r
1593 // not found form, continue scan IfrRecord list\r
1594 //\r
1595 preNode = tNode;\r
1596 pNode = tNode->mNext;\r
1597 continue;\r
1598 }\r
1599 }\r
1600 }\r
1601 //\r
1602 // next node\r
1603 //\r
1604 preNode = pNode;\r
1605 pNode = pNode->mNext; \r
1606 }\r
1607 \r
1608 //\r
1609 // Update Ifr Opcode Offset\r
1610 //\r
1611 if (Status == VFR_RETURN_SUCCESS) {\r
4afd3d04 1612 IfrAdjustOffsetForRecord ();\r
30fdf114
LG
1613 }\r
1614 return Status;\r
1615}\r
1616\r
74bbe31b
DB
1617/**\r
1618 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not\r
1619 given by expression, should save the default info for the Buffer VarStore.\r
1620\r
1621 @param DefaultId The default id.\r
1622 @param pQuestionNode Point to the question opcode node.\r
1623 @param Value The default value.\r
1624**/\r
1625VOID\r
1626CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (\r
1627 IN UINT16 DefaultId,\r
1628 IN SIfrRecord *pQuestionNode,\r
1629 IN EFI_IFR_TYPE_VALUE Value\r
1630 )\r
1631{\r
1632 CHAR8 *VarStoreName = NULL;\r
1633 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1634 EFI_GUID *VarGuid = NULL;\r
1635 EFI_VARSTORE_INFO VarInfo;\r
1636 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1637 EFI_IFR_OP_HEADER *pQuestionOpHead;\r
1638\r
1639 pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
1640 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);\r
1641\r
1642 //\r
1643 // Get the Var Store name and type.\r
1644 //\r
1645 gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);\r
1646 VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);\r
1647 VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);\r
1648\r
1649 //\r
1650 // Only for Buffer storage need to save the default info in the storage.\r
1651 // Other type storage, just return.\r
1652 //\r
1653 if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {\r
1654 return;\r
1655 } else {\r
1656 VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;\r
1657 VarInfo.mVarStoreId = QuestionHead->VarStoreId;\r
1658 }\r
1659\r
1660 //\r
1661 // Get the buffer storage info about this question.\r
1662 //\r
1663 gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);\r
1664\r
1665 //\r
1666 // Add action.\r
1667 //\r
1668 gCVfrDefaultStore.BufferVarStoreAltConfigAdd (\r
1669 DefaultId,\r
1670 VarInfo,\r
1671 VarStoreName,\r
1672 VarGuid,\r
1673 VarInfo.mVarType,\r
1674 Value\r
1675 );\r
1676}\r
1677\r
1678/**\r
1679 Record the number and default id of all defaultstore opcode.\r
1680\r
1681**/\r
1682VOID\r
1683CIfrRecordInfoDB::IfrGetDefaultStoreInfo (\r
1684 VOID\r
1685 )\r
1686{\r
1687 SIfrRecord *pNode;\r
1688 EFI_IFR_OP_HEADER *pOpHead;\r
1689 EFI_IFR_DEFAULTSTORE *DefaultStore;\r
1690\r
1691 pNode = mIfrRecordListHead;\r
1692 mAllDefaultTypeCount = 0;\r
1693\r
1694 while (pNode != NULL) {\r
1695 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1696\r
1697 if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){\r
1698 DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;\r
1699 mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;\r
1700 }\r
1701 pNode = pNode->mNext;\r
1702 }\r
1703}\r
1704\r
1705/**\r
1706 Create new default opcode record.\r
1707\r
1708 @param Size The new default opcode size.\r
1709 @param DefaultId The new default id.\r
1710 @param Type The new default type.\r
1711 @param LineNo The line number of the new record.\r
1712 @param Value The new default value.\r
1713\r
1714**/\r
1715VOID\r
1716CIfrRecordInfoDB::IfrCreateDefaultRecord(\r
1717 IN UINT8 Size,\r
1718 IN UINT16 DefaultId,\r
1719 IN UINT8 Type,\r
1720 IN UINT32 LineNo,\r
1721 IN EFI_IFR_TYPE_VALUE Value\r
1722 )\r
1723{\r
1724 CIfrDefault *DObj;\r
1725 CIfrDefault2 *DObj2;\r
1726\r
1727 DObj = NULL;\r
1728 DObj2 = NULL;\r
1729\r
1730 if (Type == EFI_IFR_TYPE_OTHER) {\r
1731 DObj2 = new CIfrDefault2 (Size);\r
1732 DObj2->SetDefaultId(DefaultId);\r
1733 DObj2->SetType(Type);\r
1734 DObj2->SetLineNo(LineNo);\r
1735 DObj2->SetScope (1);\r
1736 delete DObj2;\r
1737 } else {\r
1738 DObj = new CIfrDefault (Size);\r
1739 DObj->SetDefaultId(DefaultId);\r
1740 DObj->SetType(Type);\r
1741 DObj->SetLineNo(LineNo);\r
1742 DObj->SetValue (Value);\r
1743 delete DObj;\r
1744 }\r
1745}\r
1746\r
1747/**\r
1748 Create new default opcode for question base on the QuestionDefaultInfo.\r
1749\r
1750 @param pQuestionNode Point to the question opcode Node.\r
1751 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.\r
1752\r
1753**/\r
1754VOID\r
1755CIfrRecordInfoDB::IfrCreateDefaultForQuestion (\r
1756 IN SIfrRecord *pQuestionNode,\r
1757 IN QuestionDefaultRecord *QuestionDefaultInfo\r
1758 )\r
1759{\r
1760 EFI_IFR_OP_HEADER *pOpHead;\r
1761 EFI_IFR_DEFAULT *Default;\r
1762 SIfrRecord *pSNode;\r
1763 SIfrRecord *pENode;\r
1764 SIfrRecord *pDefaultNode;\r
1765 CIfrObj *Obj;\r
1766 CHAR8 *ObjBinBuf;\r
1767 UINT8 ScopeCount;\r
1768 UINT8 OpcodeNumber;\r
1769 UINT8 OpcodeCount;\r
1770 UINT8 DefaultSize;\r
1771 EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;\r
1772 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;\r
1773\r
1774 CheckBoxDefaultValue.b = 1;\r
1775 pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
1776 ScopeCount = 0;\r
1777 OpcodeCount = 0;\r
1778 Obj = NULL;\r
1779\r
1780 //\r
1781 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1782 //\r
1783 gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;\r
1784 //\r
1785 // Case 1:\r
1786 // For oneof, the default with smallest default id is given by the option flag.\r
1787 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).\r
1788 //\r
1789 if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
1790 DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;\r
1791 DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);\r
1792 DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
1793 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1794 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1795 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);\r
1796 //\r
1797 // Save the new created default in the buffer storage.\r
1798 //\r
1799 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);\r
1800 }\r
1801 }\r
1802 return;\r
1803 }\r
1804\r
1805 //\r
1806 // Case2:\r
1807 // For checkbox, the default with smallest default id is given by the question flag.\r
1808 // And create the missing defaults with true value.\r
1809 //\r
1810 if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
1811 DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);\r
1812 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1813 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1814 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);\r
1815 //\r
1816 // Save the new created default.\r
1817 //\r
1818 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);\r
1819 }\r
1820 }\r
1821 return;\r
1822 }\r
1823\r
1824 //\r
1825 // Case3:\r
1826 // The default with smallest default id is given by the default opcode.\r
1827 // So create the missing defaults base on the value in the default opcode.\r
1828 //\r
1829\r
1830 //\r
1831 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.\r
1832 //\r
1833 pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;\r
1834 Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;\r
1835 //\r
1836 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1837 //\r
1838 gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;\r
1839\r
1840 if (Default->Type == EFI_IFR_TYPE_OTHER) {\r
1841 //\r
1842 // EFI_IFR_DEFAULT_2 opcode.\r
1843 //\r
1844 // Point to the first expression opcode.\r
1845 //\r
1846 pSNode = pDefaultNode->mNext;\r
61eb9834 1847 pENode = NULL;\r
74bbe31b
DB
1848 ScopeCount++;\r
1849 //\r
1850 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)\r
1851 //\r
1852 while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {\r
1853 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1854 if (pOpHead->Scope == 1) {\r
1855 ScopeCount++;\r
1856 }\r
1857 if (pOpHead->OpCode == EFI_IFR_END_OP) {\r
1858 ScopeCount--;\r
1859 }\r
1860 pENode = pSNode;\r
1861 pSNode = pSNode->mNext;\r
1862 OpcodeCount++;\r
1863 }\r
9b78c54a
HW
1864\r
1865 assert (pSNode);\r
1866 assert (pENode);\r
1867\r
74bbe31b
DB
1868 //\r
1869 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
1870 //\r
1871 gAdjustOpcodeOffset = pSNode->mOffset;\r
1872 //\r
1873 // Create new default opcode node for missing default.\r
1874 //\r
1875 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1876 OpcodeNumber = OpcodeCount;\r
1877 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1878 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);\r
1879 //\r
1880 // Point to the first expression opcode node.\r
1881 //\r
1882 pSNode = pDefaultNode->mNext;\r
1883 //\r
1884 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.\r
1885 //\r
1886 while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {\r
1887 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1888 Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);\r
9b78c54a 1889 assert (Obj != NULL);\r
74bbe31b
DB
1890 Obj->SetLineNo (pSNode->mLineNo);\r
1891 ObjBinBuf = Obj->GetObjBinAddr();\r
1892 memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);\r
1893 delete Obj;\r
1894 pSNode = pSNode->mNext;\r
1895 }\r
1896 }\r
1897 }\r
1898 } else {\r
1899 //\r
1900 // EFI_IFR_DEFAULT opcode.\r
1901 //\r
1902 // Create new default opcode node for missing default.\r
1903 //\r
1904 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1905 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1906 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);\r
1907 //\r
1908 // Save the new created default in the buffer storage..\r
1909 //\r
1910 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);\r
1911 }\r
1912 }\r
1913 }\r
1914}\r
1915\r
1916/**\r
1917 Parse the default information in a question, get the QuestionDefaultInfo.\r
1918\r
1919 @param pQuestionNode Point to the question record Node.\r
1920 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.\r
1921**/\r
1922VOID\r
1923CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(\r
1924 IN SIfrRecord *pQuestionNode,\r
1925 OUT QuestionDefaultRecord *QuestionDefaultInfo\r
1926 )\r
1927{\r
1928 SIfrRecord *pSNode;\r
1929 EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;\r
1930 EFI_IFR_OP_HEADER *pSOpHead;\r
1931 EFI_IFR_CHECKBOX *CheckBoxOpcode;\r
1932 EFI_IFR_DEFAULT *DefaultOpcode;\r
1933 BOOLEAN IsOneOfOpcode;\r
1934 UINT16 SmallestDefaultId;\r
1935 UINT8 ScopeCount;\r
1936\r
1937 SmallestDefaultId = 0xffff;\r
1938 IsOneOfOpcode = FALSE;\r
1939 ScopeCount = 0;\r
1940 pSNode = pQuestionNode;\r
1941\r
1942 //\r
1943 // Parse all the opcodes in the Question.\r
1944 //\r
1945 while (pSNode != NULL) {\r
1946 pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
1947 //\r
1948 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.\r
1949 // Scopes may be nested within other scopes.\r
1950 // When finishing parsing a question, the scope count must be zero.\r
1951 //\r
1952 if (pSOpHead->Scope == 1) {\r
1953 ScopeCount++;\r
1954 }\r
1955 if (pSOpHead->OpCode == EFI_IFR_END_OP) {\r
1956 ScopeCount--;\r
1957 }\r
1958 //\r
1959 // Check whether finishing parsing a question.\r
1960 //\r
1961 if (ScopeCount == 0) {\r
1962 break;\r
1963 }\r
1964\r
1965 //\r
1966 // Record the default information in the question.\r
1967 //\r
1968 switch (pSOpHead->OpCode) {\r
1969 case EFI_IFR_ONE_OF_OP:\r
1970 IsOneOfOpcode = TRUE;\r
1971 break;\r
1972 case EFI_IFR_CHECKBOX_OP:\r
1973 //\r
1974 // The default info of check box may be given by flag.\r
1975 // So need to check the flag of check box.\r
1976 //\r
1977 CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;\r
1978 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {\r
1979 //\r
1980 // Check whether need to update the smallest default id.\r
1981 //\r
1982 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
1983 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
1984 }\r
1985 //\r
1986 // Update the QuestionDefaultInfo.\r
1987 //\r
1988 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
1989 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
1990 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
1991 QuestionDefaultInfo->mDefaultNumber ++;\r
1992 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
1993 }\r
1994 break;\r
1995 }\r
1996 }\r
1997 }\r
1998 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {\r
1999 //\r
2000 // Check whether need to update the smallest default id.\r
2001 //\r
2002 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2003 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\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_MANUFACTURING) {\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 break;\r
2019 case EFI_IFR_ONE_OF_OPTION_OP:\r
2020 if (!IsOneOfOpcode) {\r
2021 //\r
2022 // Only check the option in oneof.\r
2023 //\r
2024 break;\r
2025 }\r
2026 OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;\r
2027 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
2028 //\r
2029 // The option is used as the standard default.\r
2030 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2031 //\r
2032 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
2033 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
2034 QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
2035 }\r
2036 //\r
2037 // Update the IsDefaultIdExist array in QuestionDefaultInfo.\r
2038 //\r
2039 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2040 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\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 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {\r
2050 //\r
2051 // This option is used as the manufacture default.\r
2052 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2053 //\r
2054 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2055 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
2056 QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
2057 }\r
2058 //\r
2059 // Update the QuestionDefaultInfo.\r
2060 //\r
2061 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
2062 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
2063 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2064 QuestionDefaultInfo->mDefaultNumber ++;\r
2065 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2066 }\r
2067 break;\r
2068 }\r
2069 }\r
2070 }\r
2071 break;\r
2072 case EFI_IFR_DEFAULT_OP:\r
2073 DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;\r
2074 //\r
2075 // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
2076 //\r
2077 if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {\r
2078 SmallestDefaultId = DefaultOpcode->DefaultId;\r
2079 QuestionDefaultInfo->mDefaultValueRecord= pSNode;\r
2080 QuestionDefaultInfo->mIsDefaultOpcode= TRUE;\r
2081 }\r
2082 //\r
2083 // Update the QuestionDefaultInfo.\r
2084 //\r
2085 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){\r
2086 if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {\r
2087 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
2088 QuestionDefaultInfo->mDefaultNumber ++;\r
2089 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
2090 }\r
2091 break;\r
2092 }\r
2093 }\r
2094 break;\r
2095 default:\r
2096 break;\r
2097 }\r
2098 //\r
2099 // Parse next opcode in this question.\r
2100 //\r
2101 pSNode = pSNode->mNext;\r
2102 }\r
2103}\r
2104\r
2105/**\r
2106 Check or add default for question if need.\r
2107\r
2108 This function will check the default info for question.\r
2109 If the question has default, but the default number < defaultstore opcode number.\r
2110 will do following two action :\r
2111\r
2112 1. if (AutoDefault) will add default for question to support all kinds of defaults.\r
2113 2. if (CheckDefault) will generate an error to tell user the question misses some default value.\r
2114\r
2115 We assume that the two options can not be TRUE at same time.\r
2116 If they are TRUE at same time, only do the action corresponding to AutoDefault option.\r
2117\r
2118 @param AutoDefault Add default for question if needed\r
2119 @param CheckDefault Check the default info, if missing default, generates an error.\r
2120\r
2121**/\r
2122VOID\r
2123CIfrRecordInfoDB::IfrCheckAddDefaultRecord (\r
2124 BOOLEAN AutoDefault,\r
2125 BOOLEAN CheckDefault\r
2126 )\r
2127{\r
2128 SIfrRecord *pNode;\r
2129 SIfrRecord *pTailNode;\r
2130 SIfrRecord *pStartAdjustNode;\r
2131 EFI_IFR_OP_HEADER *pOpHead;\r
2132 QuestionDefaultRecord QuestionDefaultInfo;\r
2133 UINT8 MissingDefaultCount;\r
2134 CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
2135\r
2136 pNode = mIfrRecordListHead;\r
2137\r
2138 //\r
2139 // Record the number and default id of all defaultstore opcode.\r
2140 //\r
2141 IfrGetDefaultStoreInfo ();\r
2142\r
2143 while (pNode != NULL) {\r
2144 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
2145 //\r
2146 // Check whether is question opcode.\r
2147 //\r
2148 if (CheckQuestionOpCode (pOpHead->OpCode)) {\r
2149 //\r
2150 // Initialize some local variables here, because they vary with question.\r
2151 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.\r
2152 //\r
2153 memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));\r
2154 pTailNode = mIfrRecordListTail;\r
2155 //\r
2156 // Get the QuestionDefaultInfo for current question.\r
2157 //\r
2158 IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);\r
2159\r
2160 if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {\r
2161 if (AutoDefault) {\r
2162 //\r
2163 // Create default for question which misses default.\r
2164 //\r
2165 IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);\r
2166\r
2167 //\r
2168 // Adjust the buffer content.\r
2169 // pStartAdjustNode->mIfrBinBuf points to the insert position.\r
2170 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.\r
2171 //\r
2172 pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);\r
2173 gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);\r
2174\r
2175 //\r
2176 // Update the record info.\r
2177 //\r
2178 IfrUpdateRecordInfoForDynamicOpcode (TRUE);\r
2179 } else if (CheckDefault) {\r
2180 //\r
2181 // Generate an error for question which misses default.\r
2182 //\r
2183 MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;\r
2184 sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);\r
2185 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);\r
2186 }\r
2187 }\r
2188 }\r
2189 //\r
2190 // parse next opcode.\r
2191 //\r
2192 pNode = pNode->mNext;\r
2193 }\r
2194}\r
2195\r
30fdf114
LG
2196CIfrRecordInfoDB gCIfrRecordInfoDB;\r
2197\r
2198VOID\r
2199CIfrObj::_EMIT_PENDING_OBJ (\r
2200 VOID\r
2201 )\r
2202{\r
2203 CHAR8 *ObjBinBuf = NULL;\r
2204 \r
2205 //\r
2206 // do nothing\r
2207 //\r
2208 if (!mDelayEmit || !gCreateOp) {\r
2209 return;\r
2210 }\r
2211\r
2212 mPkgOffset = gCFormPkg.GetPkgLength ();\r
2213 //\r
2214 // update data buffer to package data\r
2215 //\r
2216 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
2217 if (ObjBinBuf != NULL) {\r
f51461c8 2218 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
30fdf114
LG
2219 }\r
2220 \r
2221 //\r
2222 // update bin buffer to package data buffer\r
2223 //\r
2224 if (mObjBinBuf != NULL) {\r
2225 delete mObjBinBuf;\r
2226 mObjBinBuf = ObjBinBuf;\r
2227 }\r
2228 \r
2229 mDelayEmit = FALSE;\r
2230}\r
2231\r
2232/*\r
2233 * The definition of CIfrObj's member function\r
2234 */\r
2235static struct {\r
2236 UINT8 mSize;\r
2237 UINT8 mScope;\r
2238} gOpcodeSizesScopeTable[] = {\r
2239 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
2240 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
2241 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
2242 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
2243 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
2244 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
2245 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
2246 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
2247 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
2248 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
2249 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
2250 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
2251 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
2252 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
2253 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
2254 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
2255 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
2256 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
2257 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
2258 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
b303ea72 2259 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
2260 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
2261 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
2262 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
2263 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
2264 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
2265 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
2266 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
2267 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
2268 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
2269 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
2270 { 0, 0 }, // 0x1F\r
2271 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
2272 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
52302d4d 2273 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
2274 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
2275 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
2276 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
2277 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
2278 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
2279 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
2280 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
52302d4d
LG
2281 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
2282 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
2283 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
2284 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
2285 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
30fdf114
LG
2286 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
2287 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
2288 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
2289 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
2290 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
2291 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
2292 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
2293 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
2294 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
2295 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
2296 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
2297 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
2298 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
2299 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
2300 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
2301 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
2302 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
2303 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
2304 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
2305 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
2306 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
2307 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
2308 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
2309 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
2310 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
2311 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
2312 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
2313 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
2314 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
2315 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
2316 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
2317 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
2318 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
2319 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
2320 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
2321 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
2322 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
2323 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
2324 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
2325 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
2326 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
2327 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
2328 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
2329 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
2330 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
2331 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
52302d4d 2332 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
2333 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
2334 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 2335 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
4afd3d04 2336 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
4234283c 2337 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
ea0f6464 2338 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
5d377616 2339 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64\r
30fdf114
LG
2340};\r
2341\r
2342#ifdef CIFROBJ_DEUBG\r
2343static struct {\r
2344 CHAR8 *mIfrName;\r
2345} gIfrObjPrintDebugTable[] = {\r
2346 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
2347 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
2348 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
2349 "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
2350 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
52302d4d 2351 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 2352 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 2353 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
2354 "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
2355 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
2356 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
2357 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
2358 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
2359 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
2360 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
52302d4d 2361 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
5d377616 2362 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",\r
30fdf114
LG
2363};\r
2364\r
2365VOID\r
2366CIFROBJ_DEBUG_PRINT (\r
2367 IN UINT8 OpCode\r
2368 )\r
2369{\r
2370 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
2371}\r
2372#else\r
2373\r
2374#define CIFROBJ_DEBUG_PRINT(OpCode)\r
2375\r
2376#endif\r
2377\r
52302d4d 2378BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
2379\r
2380CIfrObj::CIfrObj (\r
2381 IN UINT8 OpCode,\r
2382 OUT CHAR8 **IfrObj,\r
2383 IN UINT8 ObjBinLen,\r
2384 IN BOOLEAN DelayEmit\r
2385 )\r
2386{\r
2387 mDelayEmit = DelayEmit;\r
2388 mPkgOffset = gCFormPkg.GetPkgLength ();\r
2389 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
2390 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
2391 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
2392\r
9b78c54a
HW
2393 assert (mObjBinBuf != NULL);\r
2394\r
30fdf114
LG
2395 if (IfrObj != NULL) {\r
2396 *IfrObj = mObjBinBuf;\r
2397 }\r
2398\r
2399 CIFROBJ_DEBUG_PRINT (OpCode);\r
2400}\r
2401\r
2402CIfrObj::~CIfrObj (\r
2403 VOID\r
2404 )\r
2405{\r
2406 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
2407 _EMIT_PENDING_OBJ ();\r
2408 }\r
2409\r
2410 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
2411}\r
2412\r
2413/*\r
2414 * The definition of CIfrObj's member function\r
2415 */\r
2416UINT8 gScopeCount = 0;\r
2417\r
2418CIfrOpHeader::CIfrOpHeader (\r
2419 IN UINT8 OpCode,\r
2420 IN VOID *StartAddr,\r
2421 IN UINT8 Length\r
2422 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
2423{\r
2424 mHeader->OpCode = OpCode;\r
2425 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
2426 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
2427}\r
2428\r
2429CIfrOpHeader::CIfrOpHeader (\r
2430 IN CIfrOpHeader &OpHdr\r
2431 )\r
2432{\r
2433 mHeader = OpHdr.mHeader;\r
2434}\r
2435\r
52302d4d 2436UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r