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