]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTool/VfrCompile: Add missing question opcode
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
... / ...
CommitLineData
1/** @file\r
2 \r
3 The definition of CFormPkg's member function\r
4\r
5Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials \r
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
28 IN CONST CHAR8 *Msg\r
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
85 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));\r
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
98 IN UINT32 BufferSize\r
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
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
181CHAR8 *\r
182CFormPkg::IfrBinBufferGet (\r
183 IN UINT32 Len\r
184 )\r
185{\r
186 CHAR8 *BinBuffer = NULL;\r
187 SBufferNode *Node = NULL;\r
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
197 Node = CreateNewNode ();\r
198 if (Node == NULL) {\r
199 return NULL;\r
200 }\r
201\r
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
262 return 0;\r
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
273 Index --;\r
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
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
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
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
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
419UINT32 gAdjustOpcodeOffset = 0;\r
420BOOLEAN gNeedAdjustOpcode = FALSE;\r
421UINT32 gAdjustOpcodeLen = 0;\r
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
503 IN CONST CHAR8 *Msg\r
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
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
655 IN CHAR8 *LastFormEndAddr,\r
656 IN CHAR8 *InsertOpcodeAddr\r
657 )\r
658{\r
659 SBufferNode *LastFormEndNode;\r
660 SBufferNode *InsertOpcodeNode;\r
661 SBufferNode *NewRestoreNodeBegin;\r
662 SBufferNode *NewRestoreNodeEnd;\r
663 SBufferNode *NewLastEndNode;\r
664 SBufferNode *TmpNode;\r
665 UINT32 NeedRestoreCodeLen;\r
666\r
667 NewRestoreNodeEnd = NULL;\r
668\r
669 LastFormEndNode = GetBinBufferNodeForAddr(LastFormEndAddr);\r
670 InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
671\r
672 if (LastFormEndNode == InsertOpcodeNode) {\r
673 //\r
674 // Create New Node to save the restore opcode.\r
675 //\r
676 NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr;\r
677 gAdjustOpcodeLen = NeedRestoreCodeLen;\r
678 NewRestoreNodeBegin = CreateNewNode ();\r
679 if (NewRestoreNodeBegin == NULL) {\r
680 return VFR_RETURN_OUT_FOR_RESOURCES;\r
681 }\r
682 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
683 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
684\r
685 //\r
686 // Override the restore buffer data.\r
687 //\r
688 memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
689 InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;\r
690 memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);\r
691 } else {\r
692 //\r
693 // Create New Node to save the restore opcode.\r
694 //\r
695 NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr;\r
696 gAdjustOpcodeLen = NeedRestoreCodeLen;\r
697 NewRestoreNodeBegin = CreateNewNode ();\r
698 if (NewRestoreNodeBegin == NULL) {\r
699 return VFR_RETURN_OUT_FOR_RESOURCES;\r
700 }\r
701 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
702 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
703 //\r
704 // Override the restore buffer data.\r
705 //\r
706 LastFormEndNode->mBufferFree -= NeedRestoreCodeLen;\r
707 //\r
708 // Link the restore data to new node.\r
709 //\r
710 NewRestoreNodeBegin->mNext = LastFormEndNode->mNext;\r
711\r
712 //\r
713 // Count the Adjust opcode len.\r
714 //\r
715 TmpNode = LastFormEndNode->mNext;\r
716 while (TmpNode != InsertOpcodeNode) {\r
717 gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;\r
718 TmpNode = TmpNode->mNext;\r
719 }\r
720\r
721 //\r
722 // Create New Node to save the last node of restore opcode.\r
723 //\r
724 NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
725 gAdjustOpcodeLen += NeedRestoreCodeLen;\r
726 if (NeedRestoreCodeLen > 0) {\r
727 NewRestoreNodeEnd = CreateNewNode ();\r
728 if (NewRestoreNodeEnd == NULL) {\r
729 return VFR_RETURN_OUT_FOR_RESOURCES;\r
730 }\r
731 memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);\r
732 NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;\r
733 //\r
734 // Override the restore buffer data.\r
735 //\r
736 memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
737 InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
738\r
739 //\r
740 // Insert the last restore data node.\r
741 //\r
742 TmpNode = GetNodeBefore (InsertOpcodeNode);\r
743 if (TmpNode == LastFormEndNode) {\r
744 NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;\r
745 } else {\r
746 TmpNode->mNext = NewRestoreNodeEnd;\r
747 }\r
748 //\r
749 // Connect the dynamic opcode node to the node before last form end node.\r
750 //\r
751 LastFormEndNode->mNext = InsertOpcodeNode;\r
752 }\r
753 }\r
754\r
755 if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {\r
756 //\r
757 // End form set opcode all in the mBufferNodeQueueTail node.\r
758 //\r
759 NewLastEndNode = CreateNewNode ();\r
760 if (NewLastEndNode == NULL) {\r
761 return VFR_RETURN_OUT_FOR_RESOURCES;\r
762 }\r
763 NewLastEndNode->mBufferStart[0] = 0x29;\r
764 NewLastEndNode->mBufferStart[1] = 0x02;\r
765 NewLastEndNode->mBufferFree += 2;\r
766\r
767 mBufferNodeQueueTail->mBufferFree -= 2;\r
768\r
769 mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
770 if (NewRestoreNodeEnd != NULL) {\r
771 NewRestoreNodeEnd->mNext = NewLastEndNode;\r
772 } else {\r
773 NewRestoreNodeBegin->mNext = NewLastEndNode;\r
774 }\r
775\r
776 mBufferNodeQueueTail = NewLastEndNode;\r
777 } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
778 TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
779 TmpNode->mNext = NewRestoreNodeBegin;\r
780 if (NewRestoreNodeEnd != NULL) {\r
781 NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
782 } else {\r
783 NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;\r
784 }\r
785 }\r
786\r
787 return VFR_RETURN_SUCCESS;\r
788}\r
789\r
790EFI_VFR_RETURN_CODE\r
791CFormPkg::DeclarePendingQuestion (\r
792 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,\r
793 IN CVfrDataStorage &lCVfrDataStorage,\r
794 IN CVfrQuestionDB &lCVfrQuestionDB,\r
795 IN EFI_GUID *LocalFormSetGuid,\r
796 IN UINT32 LineNo,\r
797 OUT CHAR8 **InsertOpcodeAddr\r
798 )\r
799{\r
800 SPendingAssign *pNode;\r
801 CHAR8 *VarStr;\r
802 UINT32 ArrayIdx;\r
803 CHAR8 FName[MAX_NAME_LEN];\r
804 CHAR8 *SName;\r
805 CHAR8 *NewStr;\r
806 UINT32 ShrinkSize;\r
807 EFI_VFR_RETURN_CODE ReturnCode;\r
808 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
809 EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;\r
810\r
811 //\r
812 // Declare all questions as Numeric in DisableIf True\r
813 //\r
814 // DisableIf\r
815 CIfrDisableIf DIObj;\r
816 DIObj.SetLineNo (LineNo);\r
817 *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
818 \r
819 //TrueOpcode\r
820 CIfrTrue TObj (LineNo);\r
821\r
822 // Declare Numeric qeustion for each undefined question.\r
823 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
824 if (pNode->mFlag == PENDING) {\r
825 CIfrNumeric CNObj;\r
826 EFI_VARSTORE_INFO Info; \r
827 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
828\r
829 CNObj.SetLineNo (LineNo);\r
830 CNObj.SetPrompt (0x0);\r
831 CNObj.SetHelp (0x0);\r
832\r
833 //\r
834 // Register this question, assume it is normal question, not date or time question\r
835 //\r
836 VarStr = pNode->mKey;\r
837 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);\r
838 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
839 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
840 return ReturnCode;\r
841 }\r
842 \r
843#ifdef VFREXP_DEBUG\r
844 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
845#endif\r
846 //\r
847 // Get Question Info, framework vfr VarName == StructName\r
848 //\r
849 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);\r
850 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
851 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");\r
852 return ReturnCode;\r
853 }\r
854 //\r
855 // Get VarStoreType\r
856 //\r
857 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
858 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
859 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
860 return ReturnCode;\r
861 }\r
862 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
863\r
864 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
865 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
866 } else {\r
867 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
868 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
869 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
870 VarStr = pNode->mKey;\r
871 //convert VarStr with store name to VarStr with structure name\r
872 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
873 if (ReturnCode == VFR_RETURN_SUCCESS) {\r
874 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
875 NewStr[0] = '\0';\r
876 strcpy (NewStr, SName);\r
877 strcat (NewStr, VarStr + strlen (FName));\r
878 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
879 delete NewStr;\r
880 }\r
881 } else {\r
882 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
883 }\r
884 }\r
885 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
886 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
887 return ReturnCode;\r
888 }\r
889\r
890 CNObj.SetQuestionId (QId);\r
891 CNObj.SetVarStoreInfo (&Info);\r
892 //\r
893 // Numeric doesn't support BOOLEAN data type. \r
894 // BOOLEAN type has the same data size to UINT8. \r
895 //\r
896 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
897 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
898 }\r
899 CNObj.SetFlags (0, Info.mVarType);\r
900 //\r
901 // Use maximum value not to limit the vaild value for the undefined question.\r
902 //\r
903 switch (Info.mVarType) {\r
904 case EFI_IFR_TYPE_NUM_SIZE_64:\r
905 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
906 ShrinkSize = 0;\r
907 break;\r
908 case EFI_IFR_TYPE_NUM_SIZE_32:\r
909 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
910 ShrinkSize = 12;\r
911 break;\r
912 case EFI_IFR_TYPE_NUM_SIZE_16:\r
913 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
914 ShrinkSize = 18;\r
915 break;\r
916 case EFI_IFR_TYPE_NUM_SIZE_8:\r
917 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
918 ShrinkSize = 21;\r
919 break;\r
920 default:\r
921 break;\r
922 }\r
923 CNObj.ShrinkBinSize (ShrinkSize);\r
924\r
925 //\r
926 // For undefined Efi VarStore type question\r
927 // Append the extended guided opcode to contain VarName\r
928 //\r
929 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
930 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
931 CVNObj.SetLineNo (LineNo);\r
932 }\r
933\r
934 //\r
935 // End for Numeric\r
936 //\r
937 CIfrEnd CEObj; \r
938 CEObj.SetLineNo (LineNo);\r
939 }\r
940 }\r
941\r
942 //\r
943 // End for DisableIf\r
944 //\r
945 CIfrEnd SEObj;\r
946 SEObj.SetLineNo (LineNo);\r
947\r
948 return VFR_RETURN_SUCCESS;\r
949}\r
950\r
951CFormPkg gCFormPkg;\r
952\r
953SIfrRecord::SIfrRecord (\r
954 VOID\r
955 )\r
956{\r
957 mIfrBinBuf = NULL;\r
958 mBinBufLen = 0;\r
959 mLineNo = 0xFFFFFFFF;\r
960 mOffset = 0xFFFFFFFF;\r
961 mNext = NULL;\r
962}\r
963\r
964SIfrRecord::~SIfrRecord (\r
965 VOID\r
966 )\r
967{\r
968 if (mIfrBinBuf != NULL) {\r
969 //delete mIfrBinBuf;\r
970 mIfrBinBuf = NULL;\r
971 }\r
972 mLineNo = 0xFFFFFFFF;\r
973 mOffset = 0xFFFFFFFF;\r
974 mBinBufLen = 0;\r
975 mNext = NULL;\r
976}\r
977\r
978CIfrRecordInfoDB::CIfrRecordInfoDB (\r
979 VOID\r
980 )\r
981{\r
982 mSwitch = TRUE;\r
983 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
984 mIfrRecordListHead = NULL;\r
985 mIfrRecordListTail = NULL;\r
986}\r
987\r
988CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
989 VOID\r
990 )\r
991{\r
992 SIfrRecord *pNode;\r
993\r
994 while (mIfrRecordListHead != NULL) {\r
995 pNode = mIfrRecordListHead;\r
996 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
997 delete pNode;\r
998 }\r
999}\r
1000\r
1001SIfrRecord *\r
1002CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
1003 IN UINT32 RecordIdx\r
1004 )\r
1005{\r
1006 UINT32 Idx;\r
1007 SIfrRecord *pNode = NULL;\r
1008\r
1009 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
1010 return NULL;\r
1011 }\r
1012\r
1013 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
1014 (Idx != RecordIdx) && (pNode != NULL);\r
1015 Idx++, pNode = pNode->mNext)\r
1016 ;\r
1017\r
1018 return pNode;\r
1019}\r
1020\r
1021UINT32\r
1022CIfrRecordInfoDB::IfrRecordRegister (\r
1023 IN UINT32 LineNo,\r
1024 IN CHAR8 *IfrBinBuf,\r
1025 IN UINT8 BinBufLen,\r
1026 IN UINT32 Offset\r
1027 )\r
1028{\r
1029 SIfrRecord *pNew;\r
1030\r
1031 if (mSwitch == FALSE) {\r
1032 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1033 }\r
1034\r
1035 if ((pNew = new SIfrRecord) == NULL) {\r
1036 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1037 }\r
1038\r
1039 if (mIfrRecordListHead == NULL) {\r
1040 mIfrRecordListHead = pNew;\r
1041 mIfrRecordListTail = pNew;\r
1042 } else {\r
1043 mIfrRecordListTail->mNext = pNew;\r
1044 mIfrRecordListTail = pNew;\r
1045 }\r
1046 mRecordCount++;\r
1047\r
1048 return mRecordCount;\r
1049}\r
1050\r
1051VOID\r
1052CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
1053 IN UINT32 RecordIdx,\r
1054 IN UINT32 LineNo,\r
1055 IN CHAR8 *BinBuf,\r
1056 IN UINT8 BinBufLen,\r
1057 IN UINT32 Offset\r
1058 )\r
1059{\r
1060 SIfrRecord *pNode;\r
1061 SIfrRecord *Prev;\r
1062\r
1063 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
1064 return;\r
1065 }\r
1066\r
1067 if (LineNo == 0) {\r
1068 //\r
1069 // Line number is not specified explicitly, try to use line number of previous opcode\r
1070 //\r
1071 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
1072 if (Prev != NULL) {\r
1073 LineNo = Prev->mLineNo;\r
1074 }\r
1075 }\r
1076\r
1077 pNode->mLineNo = LineNo;\r
1078 pNode->mOffset = Offset;\r
1079 pNode->mBinBufLen = BinBufLen;\r
1080 pNode->mIfrBinBuf = BinBuf;\r
1081\r
1082}\r
1083\r
1084VOID\r
1085CIfrRecordInfoDB::IfrRecordOutput (\r
1086 OUT PACKAGE_DATA &TBuffer\r
1087 )\r
1088{\r
1089 CHAR8 *Temp;\r
1090 SIfrRecord *pNode; \r
1091\r
1092 if (TBuffer.Buffer != NULL) {\r
1093 delete TBuffer.Buffer;\r
1094 }\r
1095\r
1096 TBuffer.Size = 0;\r
1097 TBuffer.Buffer = NULL;\r
1098\r
1099\r
1100 if (mSwitch == FALSE) {\r
1101 return;\r
1102 } \r
1103 \r
1104 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1105 TBuffer.Size += pNode->mBinBufLen;\r
1106 }\r
1107 \r
1108 if (TBuffer.Size != 0) {\r
1109 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
1110 } else {\r
1111 return;\r
1112 }\r
1113 \r
1114 Temp = TBuffer.Buffer;\r
1115\r
1116 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1117 if (pNode->mIfrBinBuf != NULL) {\r
1118 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
1119 Temp += pNode->mBinBufLen;\r
1120 }\r
1121 }\r
1122\r
1123 return; \r
1124} \r
1125\r
1126VOID\r
1127CIfrRecordInfoDB::IfrRecordOutput (\r
1128 IN FILE *File,\r
1129 IN UINT32 LineNo\r
1130 )\r
1131{\r
1132 SIfrRecord *pNode;\r
1133 UINT8 Index;\r
1134 UINT32 TotalSize;\r
1135\r
1136 if (mSwitch == FALSE) {\r
1137 return;\r
1138 }\r
1139\r
1140 if (File == NULL) {\r
1141 return;\r
1142 }\r
1143\r
1144 TotalSize = 0;\r
1145\r
1146 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1147 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
1148 fprintf (File, ">%08X: ", pNode->mOffset);\r
1149 TotalSize += pNode->mBinBufLen;\r
1150 if (pNode->mIfrBinBuf != NULL) {\r
1151 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
1152 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
1153 }\r
1154 }\r
1155 fprintf (File, "\n");\r
1156 }\r
1157 }\r
1158 \r
1159 if (LineNo == 0) {\r
1160 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
1161 }\r
1162}\r
1163\r
1164//\r
1165// for framework vfr file\r
1166// adjust opcode sequence for uefi IFR format\r
1167// adjust inconsistent and varstore into the right position.\r
1168//\r
1169BOOLEAN\r
1170CIfrRecordInfoDB::CheckQuestionOpCode (\r
1171 IN UINT8 OpCode\r
1172 )\r
1173{\r
1174 switch (OpCode) {\r
1175 case EFI_IFR_CHECKBOX_OP:\r
1176 case EFI_IFR_NUMERIC_OP:\r
1177 case EFI_IFR_PASSWORD_OP:\r
1178 case EFI_IFR_ONE_OF_OP:\r
1179 case EFI_IFR_ACTION_OP:\r
1180 case EFI_IFR_STRING_OP:\r
1181 case EFI_IFR_DATE_OP:\r
1182 case EFI_IFR_TIME_OP:\r
1183 case EFI_IFR_ORDERED_LIST_OP:\r
1184 case EFI_IFR_REF_OP:\r
1185 case EFI_IFR_RESET_BUTTON_OP:\r
1186 return TRUE;\r
1187 default:\r
1188 return FALSE;\r
1189 }\r
1190}\r
1191\r
1192BOOLEAN\r
1193CIfrRecordInfoDB::CheckIdOpCode (\r
1194 IN UINT8 OpCode\r
1195 )\r
1196{\r
1197 switch (OpCode) {\r
1198 case EFI_IFR_EQ_ID_VAL_OP:\r
1199 case EFI_IFR_EQ_ID_ID_OP:\r
1200 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
1201 case EFI_IFR_QUESTION_REF1_OP:\r
1202 return TRUE;\r
1203 default:\r
1204 return FALSE;\r
1205 }\r
1206} \r
1207\r
1208EFI_QUESTION_ID\r
1209CIfrRecordInfoDB::GetOpcodeQuestionId (\r
1210 IN EFI_IFR_OP_HEADER *OpHead\r
1211 )\r
1212{\r
1213 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1214 \r
1215 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
1216 \r
1217 return QuestionHead->QuestionId;\r
1218}\r
1219\r
1220SIfrRecord *\r
1221CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
1222 IN UINT32 Offset\r
1223 )\r
1224{\r
1225 SIfrRecord *pNode = NULL;\r
1226\r
1227 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1228 if (pNode->mOffset == Offset) {\r
1229 return pNode;\r
1230 }\r
1231 }\r
1232\r
1233 return pNode;\r
1234}\r
1235\r
1236/*\r
1237 Add just the op code position.\r
1238\r
1239 From\r
1240 \r
1241 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |\r
1242 \r
1243 To\r
1244 \r
1245 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |\r
1246\r
1247*/\r
1248BOOLEAN\r
1249CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
1250 VOID\r
1251 )\r
1252{\r
1253 UINT32 OpcodeOffset;\r
1254 SIfrRecord *pNode, *pPreNode;\r
1255 SIfrRecord *pStartNode, *pNodeBeforeStart;\r
1256 SIfrRecord *pEndNode;\r
1257 \r
1258 pStartNode = NULL;\r
1259 pEndNode = NULL;\r
1260 OpcodeOffset = 0;\r
1261\r
1262 //\r
1263 // Base on the offset info to get the node.\r
1264 //\r
1265 for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {\r
1266 if (OpcodeOffset == gAdjustOpcodeOffset) {\r
1267 pStartNode = pNode;\r
1268 pNodeBeforeStart = pPreNode;\r
1269 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
1270 pEndNode = pPreNode;\r
1271 }\r
1272\r
1273 OpcodeOffset += pNode->mBinBufLen;\r
1274 }\r
1275\r
1276 //\r
1277 // Check the value.\r
1278 //\r
1279 if (pEndNode == NULL || pStartNode == NULL) {\r
1280 return FALSE;\r
1281 }\r
1282\r
1283 //\r
1284 // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
1285 //\r
1286 pNodeBeforeStart->mNext = pEndNode->mNext;\r
1287 pPreNode->mNext = pStartNode;\r
1288 pEndNode->mNext = mIfrRecordListTail;\r
1289\r
1290 return TRUE;\r
1291}\r
1292\r
1293VOID\r
1294CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
1295 VOID\r
1296 )\r
1297{\r
1298 UINT32 OpcodeOffset;\r
1299 SIfrRecord *pNode;\r
1300\r
1301 OpcodeOffset = 0;\r
1302 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1303 pNode->mOffset = OpcodeOffset;\r
1304 OpcodeOffset += pNode->mBinBufLen;\r
1305 }\r
1306}\r
1307\r
1308EFI_VFR_RETURN_CODE\r
1309CIfrRecordInfoDB::IfrRecordAdjust (\r
1310 VOID\r
1311 )\r
1312{\r
1313 SIfrRecord *pNode, *preNode;\r
1314 SIfrRecord *uNode, *tNode;\r
1315 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
1316 EFI_QUESTION_ID QuestionId;\r
1317 UINT32 StackCount;\r
1318 UINT32 QuestionScope;\r
1319 UINT32 OpcodeOffset;\r
1320 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
1321 EFI_VFR_RETURN_CODE Status;\r
1322\r
1323 //\r
1324 // Init local variable\r
1325 //\r
1326 Status = VFR_RETURN_SUCCESS;\r
1327 pNode = mIfrRecordListHead;\r
1328 preNode = pNode;\r
1329 QuestionScope = 0;\r
1330 while (pNode != NULL) {\r
1331 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1332 \r
1333 //\r
1334 // make sure the inconsistent opcode in question scope\r
1335 //\r
1336 if (QuestionScope > 0) {\r
1337 QuestionScope += OpHead->Scope;\r
1338 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1339 QuestionScope --;\r
1340 }\r
1341 }\r
1342 \r
1343 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1344 QuestionScope = 1;\r
1345 }\r
1346 //\r
1347 // for the inconsistent opcode not in question scope, adjust it\r
1348 //\r
1349 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1350 //\r
1351 // for inconsistent opcode not in question scope\r
1352 //\r
1353\r
1354 //\r
1355 // Count inconsistent opcode Scope \r
1356 //\r
1357 StackCount = OpHead->Scope;\r
1358 QuestionId = EFI_QUESTION_ID_INVALID;\r
1359 tNode = pNode;\r
1360 while (tNode != NULL && StackCount > 0) {\r
1361 tNode = tNode->mNext;\r
1362 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1363 //\r
1364 // Calculate Scope Number\r
1365 //\r
1366 StackCount += tOpHead->Scope;\r
1367 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1368 StackCount --;\r
1369 }\r
1370 //\r
1371 // by IdEqual opcode to get QuestionId\r
1372 //\r
1373 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1374 CheckIdOpCode (tOpHead->OpCode)) {\r
1375 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1376 }\r
1377 }\r
1378 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1379 //\r
1380 // report error; not found\r
1381 //\r
1382 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1383 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1384 Status = VFR_RETURN_MISMATCHED;\r
1385 break;\r
1386 }\r
1387 //\r
1388 // extract inconsistent opcode list\r
1389 // pNode is Incosistent opcode, tNode is End Opcode\r
1390 //\r
1391 \r
1392 //\r
1393 // insert inconsistent opcode list into the right question scope by questionid\r
1394 //\r
1395 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1396 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1397 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1398 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1399 break;\r
1400 }\r
1401 }\r
1402 //\r
1403 // insert inconsistent opcode list and check LATE_CHECK flag\r
1404 //\r
1405 if (uNode != NULL) {\r
1406 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1407 //\r
1408 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1409 //\r
1410 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1411 }\r
1412 \r
1413 //\r
1414 // skip the default storage for Date and Time\r
1415 //\r
1416 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1417 uNode = uNode->mNext;\r
1418 }\r
1419\r
1420 preNode->mNext = tNode->mNext;\r
1421 tNode->mNext = uNode->mNext;\r
1422 uNode->mNext = pNode;\r
1423 //\r
1424 // reset pNode to head list, scan the whole list again.\r
1425 //\r
1426 pNode = mIfrRecordListHead;\r
1427 preNode = pNode;\r
1428 QuestionScope = 0;\r
1429 continue;\r
1430 } else {\r
1431 //\r
1432 // not found matched question id, report error\r
1433 //\r
1434 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1435 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1436 Status = VFR_RETURN_MISMATCHED;\r
1437 break;\r
1438 }\r
1439 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1440 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1441 //\r
1442 // for new added group of varstore opcode\r
1443 //\r
1444 tNode = pNode;\r
1445 while (tNode->mNext != NULL) {\r
1446 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1447 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1448 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1449 break; \r
1450 }\r
1451 tNode = tNode->mNext;\r
1452 }\r
1453\r
1454 if (tNode->mNext == NULL) {\r
1455 //\r
1456 // invalid IfrCode, IfrCode end by EndOpCode\r
1457 // \r
1458 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1459 Status = VFR_RETURN_MISMATCHED;\r
1460 break;\r
1461 }\r
1462 \r
1463 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1464 //\r
1465 // not new added varstore, which are not needed to be adjust.\r
1466 //\r
1467 preNode = tNode;\r
1468 pNode = tNode->mNext;\r
1469 continue; \r
1470 } else {\r
1471 //\r
1472 // move new added varstore opcode to the position befor form opcode \r
1473 // varstore opcode between pNode and tNode\r
1474 //\r
1475\r
1476 //\r
1477 // search form opcode from begin\r
1478 //\r
1479 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1480 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1481 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1482 break;\r
1483 }\r
1484 }\r
1485 //\r
1486 // Insert varstore opcode beform form opcode if form opcode is found\r
1487 //\r
1488 if (uNode->mNext != NULL) {\r
1489 preNode->mNext = tNode->mNext;\r
1490 tNode->mNext = uNode->mNext;\r
1491 uNode->mNext = pNode;\r
1492 //\r
1493 // reset pNode to head list, scan the whole list again.\r
1494 //\r
1495 pNode = mIfrRecordListHead;\r
1496 preNode = pNode;\r
1497 QuestionScope = 0;\r
1498 continue;\r
1499 } else {\r
1500 //\r
1501 // not found form, continue scan IfrRecord list\r
1502 //\r
1503 preNode = tNode;\r
1504 pNode = tNode->mNext;\r
1505 continue;\r
1506 }\r
1507 }\r
1508 }\r
1509 //\r
1510 // next node\r
1511 //\r
1512 preNode = pNode;\r
1513 pNode = pNode->mNext; \r
1514 }\r
1515 \r
1516 //\r
1517 // Update Ifr Opcode Offset\r
1518 //\r
1519 if (Status == VFR_RETURN_SUCCESS) {\r
1520 IfrAdjustOffsetForRecord ();\r
1521 }\r
1522 return Status;\r
1523}\r
1524\r
1525CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1526\r
1527VOID\r
1528CIfrObj::_EMIT_PENDING_OBJ (\r
1529 VOID\r
1530 )\r
1531{\r
1532 CHAR8 *ObjBinBuf = NULL;\r
1533 \r
1534 //\r
1535 // do nothing\r
1536 //\r
1537 if (!mDelayEmit || !gCreateOp) {\r
1538 return;\r
1539 }\r
1540\r
1541 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1542 //\r
1543 // update data buffer to package data\r
1544 //\r
1545 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1546 if (ObjBinBuf != NULL) {\r
1547 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1548 }\r
1549 \r
1550 //\r
1551 // update bin buffer to package data buffer\r
1552 //\r
1553 if (mObjBinBuf != NULL) {\r
1554 delete mObjBinBuf;\r
1555 mObjBinBuf = ObjBinBuf;\r
1556 }\r
1557 \r
1558 mDelayEmit = FALSE;\r
1559}\r
1560\r
1561/*\r
1562 * The definition of CIfrObj's member function\r
1563 */\r
1564static struct {\r
1565 UINT8 mSize;\r
1566 UINT8 mScope;\r
1567} gOpcodeSizesScopeTable[] = {\r
1568 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1569 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1570 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1571 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1572 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1573 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1574 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1575 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1576 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1577 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1578 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1579 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1580 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1581 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1582 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1583 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1584 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1585 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1586 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1587 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
1588 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
1589 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1590 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1591 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1592 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1593 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1594 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1595 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1596 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1597 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1598 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1599 { 0, 0 }, // 0x1F\r
1600 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1601 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
1602 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
1603 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1604 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1605 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1606 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1607 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1608 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1609 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
1610 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
1611 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
1612 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
1613 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
1614 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
1615 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1616 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1617 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1618 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1619 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1620 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1621 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1622 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1623 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1624 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1625 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1626 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1627 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1628 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1629 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1630 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1631 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1632 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1633 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1634 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1635 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1636 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1637 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1638 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1639 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1640 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1641 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1642 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1643 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1644 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1645 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1646 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1647 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1648 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1649 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1650 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1651 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1652 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1653 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1654 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1655 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1656 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1657 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1658 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1659 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1660 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
1661 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
1662 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1663 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
1664 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
1665 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
1666 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
1667 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
1668 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64\r
1669};\r
1670\r
1671#ifdef CIFROBJ_DEUBG\r
1672static struct {\r
1673 CHAR8 *mIfrName;\r
1674} gIfrObjPrintDebugTable[] = {\r
1675 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1676 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1677 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1678 "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
1679 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
1680 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
1681 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
1682 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
1683 "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
1684 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1685 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1686 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1687 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1688 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1689 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
1690 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
1691 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",\r
1692};\r
1693\r
1694VOID\r
1695CIFROBJ_DEBUG_PRINT (\r
1696 IN UINT8 OpCode\r
1697 )\r
1698{\r
1699 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1700}\r
1701#else\r
1702\r
1703#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1704\r
1705#endif\r
1706\r
1707BOOLEAN gCreateOp = TRUE;\r
1708\r
1709CIfrObj::CIfrObj (\r
1710 IN UINT8 OpCode,\r
1711 OUT CHAR8 **IfrObj,\r
1712 IN UINT8 ObjBinLen,\r
1713 IN BOOLEAN DelayEmit\r
1714 )\r
1715{\r
1716 mDelayEmit = DelayEmit;\r
1717 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1718 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1719 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1720 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1721\r
1722 if (IfrObj != NULL) {\r
1723 *IfrObj = mObjBinBuf;\r
1724 }\r
1725\r
1726 CIFROBJ_DEBUG_PRINT (OpCode);\r
1727}\r
1728\r
1729CIfrObj::~CIfrObj (\r
1730 VOID\r
1731 )\r
1732{\r
1733 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1734 _EMIT_PENDING_OBJ ();\r
1735 }\r
1736\r
1737 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1738}\r
1739\r
1740/*\r
1741 * The definition of CIfrObj's member function\r
1742 */\r
1743UINT8 gScopeCount = 0;\r
1744\r
1745CIfrOpHeader::CIfrOpHeader (\r
1746 IN UINT8 OpCode,\r
1747 IN VOID *StartAddr,\r
1748 IN UINT8 Length\r
1749 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1750{\r
1751 mHeader->OpCode = OpCode;\r
1752 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1753 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1754}\r
1755\r
1756CIfrOpHeader::CIfrOpHeader (\r
1757 IN CIfrOpHeader &OpHdr\r
1758 )\r
1759{\r
1760 mHeader = OpHdr.mHeader;\r
1761}\r
1762\r
1763UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r