]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
MdeModulePkg: update comments for question.
[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 - 2013, 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 return TRUE;\r
1185 default:\r
1186 return FALSE;\r
1187 }\r
1188}\r
1189\r
1190BOOLEAN\r
1191CIfrRecordInfoDB::CheckIdOpCode (\r
1192 IN UINT8 OpCode\r
1193 )\r
1194{\r
1195 switch (OpCode) {\r
1196 case EFI_IFR_EQ_ID_VAL_OP:\r
1197 case EFI_IFR_EQ_ID_ID_OP:\r
1198 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
1199 case EFI_IFR_QUESTION_REF1_OP:\r
1200 return TRUE;\r
1201 default:\r
1202 return FALSE;\r
1203 }\r
1204} \r
1205\r
1206EFI_QUESTION_ID\r
1207CIfrRecordInfoDB::GetOpcodeQuestionId (\r
1208 IN EFI_IFR_OP_HEADER *OpHead\r
1209 )\r
1210{\r
1211 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1212 \r
1213 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
1214 \r
1215 return QuestionHead->QuestionId;\r
1216}\r
1217\r
1218SIfrRecord *\r
1219CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
1220 IN UINT32 Offset\r
1221 )\r
1222{\r
1223 SIfrRecord *pNode = NULL;\r
1224\r
1225 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1226 if (pNode->mOffset == Offset) {\r
1227 return pNode;\r
1228 }\r
1229 }\r
1230\r
1231 return pNode;\r
1232}\r
1233\r
1234/*\r
1235 Add just the op code position.\r
1236\r
1237 From\r
1238 \r
1239 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |\r
1240 \r
1241 To\r
1242 \r
1243 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |\r
1244\r
1245*/\r
1246BOOLEAN\r
1247CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
1248 VOID\r
1249 )\r
1250{\r
1251 UINT32 OpcodeOffset;\r
1252 SIfrRecord *pNode, *pPreNode;\r
1253 SIfrRecord *pStartNode, *pNodeBeforeStart;\r
1254 SIfrRecord *pEndNode;\r
1255 \r
1256 pStartNode = NULL;\r
1257 pEndNode = NULL;\r
1258 OpcodeOffset = 0;\r
1259\r
1260 //\r
1261 // Base on the offset info to get the node.\r
1262 //\r
1263 for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {\r
1264 if (OpcodeOffset == gAdjustOpcodeOffset) {\r
1265 pStartNode = pNode;\r
1266 pNodeBeforeStart = pPreNode;\r
1267 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
1268 pEndNode = pPreNode;\r
1269 }\r
1270\r
1271 OpcodeOffset += pNode->mBinBufLen;\r
1272 }\r
1273\r
1274 //\r
1275 // Check the value.\r
1276 //\r
1277 if (pEndNode == NULL || pStartNode == NULL) {\r
1278 return FALSE;\r
1279 }\r
1280\r
1281 //\r
1282 // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
1283 //\r
1284 pNodeBeforeStart->mNext = pEndNode->mNext;\r
1285 pPreNode->mNext = pStartNode;\r
1286 pEndNode->mNext = mIfrRecordListTail;\r
1287\r
1288 return TRUE;\r
1289}\r
1290\r
1291VOID\r
1292CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
1293 VOID\r
1294 )\r
1295{\r
1296 UINT32 OpcodeOffset;\r
1297 SIfrRecord *pNode;\r
1298\r
1299 OpcodeOffset = 0;\r
1300 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1301 pNode->mOffset = OpcodeOffset;\r
1302 OpcodeOffset += pNode->mBinBufLen;\r
1303 }\r
1304}\r
1305\r
1306EFI_VFR_RETURN_CODE\r
1307CIfrRecordInfoDB::IfrRecordAdjust (\r
1308 VOID\r
1309 )\r
1310{\r
1311 SIfrRecord *pNode, *preNode;\r
1312 SIfrRecord *uNode, *tNode;\r
1313 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
1314 EFI_QUESTION_ID QuestionId;\r
1315 UINT32 StackCount;\r
1316 UINT32 QuestionScope;\r
1317 UINT32 OpcodeOffset;\r
1318 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
1319 EFI_VFR_RETURN_CODE Status;\r
1320\r
1321 //\r
1322 // Init local variable\r
1323 //\r
1324 Status = VFR_RETURN_SUCCESS;\r
1325 pNode = mIfrRecordListHead;\r
1326 preNode = pNode;\r
1327 QuestionScope = 0;\r
1328 while (pNode != NULL) {\r
1329 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1330 \r
1331 //\r
1332 // make sure the inconsistent opcode in question scope\r
1333 //\r
1334 if (QuestionScope > 0) {\r
1335 QuestionScope += OpHead->Scope;\r
1336 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1337 QuestionScope --;\r
1338 }\r
1339 }\r
1340 \r
1341 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1342 QuestionScope = 1;\r
1343 }\r
1344 //\r
1345 // for the inconsistent opcode not in question scope, adjust it\r
1346 //\r
1347 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1348 //\r
1349 // for inconsistent opcode not in question scope\r
1350 //\r
1351\r
1352 //\r
1353 // Count inconsistent opcode Scope \r
1354 //\r
1355 StackCount = OpHead->Scope;\r
1356 QuestionId = EFI_QUESTION_ID_INVALID;\r
1357 tNode = pNode;\r
1358 while (tNode != NULL && StackCount > 0) {\r
1359 tNode = tNode->mNext;\r
1360 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1361 //\r
1362 // Calculate Scope Number\r
1363 //\r
1364 StackCount += tOpHead->Scope;\r
1365 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1366 StackCount --;\r
1367 }\r
1368 //\r
1369 // by IdEqual opcode to get QuestionId\r
1370 //\r
1371 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1372 CheckIdOpCode (tOpHead->OpCode)) {\r
1373 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1374 }\r
1375 }\r
1376 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1377 //\r
1378 // report error; not found\r
1379 //\r
1380 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1381 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1382 Status = VFR_RETURN_MISMATCHED;\r
1383 break;\r
1384 }\r
1385 //\r
1386 // extract inconsistent opcode list\r
1387 // pNode is Incosistent opcode, tNode is End Opcode\r
1388 //\r
1389 \r
1390 //\r
1391 // insert inconsistent opcode list into the right question scope by questionid\r
1392 //\r
1393 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1394 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1395 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1396 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1397 break;\r
1398 }\r
1399 }\r
1400 //\r
1401 // insert inconsistent opcode list and check LATE_CHECK flag\r
1402 //\r
1403 if (uNode != NULL) {\r
1404 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1405 //\r
1406 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1407 //\r
1408 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1409 }\r
1410 \r
1411 //\r
1412 // skip the default storage for Date and Time\r
1413 //\r
1414 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1415 uNode = uNode->mNext;\r
1416 }\r
1417\r
1418 preNode->mNext = tNode->mNext;\r
1419 tNode->mNext = uNode->mNext;\r
1420 uNode->mNext = pNode;\r
1421 //\r
1422 // reset pNode to head list, scan the whole list again.\r
1423 //\r
1424 pNode = mIfrRecordListHead;\r
1425 preNode = pNode;\r
1426 QuestionScope = 0;\r
1427 continue;\r
1428 } else {\r
1429 //\r
1430 // not found matched question id, report error\r
1431 //\r
1432 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1433 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1434 Status = VFR_RETURN_MISMATCHED;\r
1435 break;\r
1436 }\r
1437 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1438 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1439 //\r
1440 // for new added group of varstore opcode\r
1441 //\r
1442 tNode = pNode;\r
1443 while (tNode->mNext != NULL) {\r
1444 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1445 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1446 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1447 break; \r
1448 }\r
1449 tNode = tNode->mNext;\r
1450 }\r
1451\r
1452 if (tNode->mNext == NULL) {\r
1453 //\r
1454 // invalid IfrCode, IfrCode end by EndOpCode\r
1455 // \r
1456 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1457 Status = VFR_RETURN_MISMATCHED;\r
1458 break;\r
1459 }\r
1460 \r
1461 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1462 //\r
1463 // not new added varstore, which are not needed to be adjust.\r
1464 //\r
1465 preNode = tNode;\r
1466 pNode = tNode->mNext;\r
1467 continue; \r
1468 } else {\r
1469 //\r
1470 // move new added varstore opcode to the position befor form opcode \r
1471 // varstore opcode between pNode and tNode\r
1472 //\r
1473\r
1474 //\r
1475 // search form opcode from begin\r
1476 //\r
1477 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1478 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1479 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1480 break;\r
1481 }\r
1482 }\r
1483 //\r
1484 // Insert varstore opcode beform form opcode if form opcode is found\r
1485 //\r
1486 if (uNode->mNext != NULL) {\r
1487 preNode->mNext = tNode->mNext;\r
1488 tNode->mNext = uNode->mNext;\r
1489 uNode->mNext = pNode;\r
1490 //\r
1491 // reset pNode to head list, scan the whole list again.\r
1492 //\r
1493 pNode = mIfrRecordListHead;\r
1494 preNode = pNode;\r
1495 QuestionScope = 0;\r
1496 continue;\r
1497 } else {\r
1498 //\r
1499 // not found form, continue scan IfrRecord list\r
1500 //\r
1501 preNode = tNode;\r
1502 pNode = tNode->mNext;\r
1503 continue;\r
1504 }\r
1505 }\r
1506 }\r
1507 //\r
1508 // next node\r
1509 //\r
1510 preNode = pNode;\r
1511 pNode = pNode->mNext; \r
1512 }\r
1513 \r
1514 //\r
1515 // Update Ifr Opcode Offset\r
1516 //\r
1517 if (Status == VFR_RETURN_SUCCESS) {\r
1518 IfrAdjustOffsetForRecord ();\r
1519 }\r
1520 return Status;\r
1521}\r
1522\r
1523CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1524\r
1525VOID\r
1526CIfrObj::_EMIT_PENDING_OBJ (\r
1527 VOID\r
1528 )\r
1529{\r
1530 CHAR8 *ObjBinBuf = NULL;\r
1531 \r
1532 //\r
1533 // do nothing\r
1534 //\r
1535 if (!mDelayEmit || !gCreateOp) {\r
1536 return;\r
1537 }\r
1538\r
1539 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1540 //\r
1541 // update data buffer to package data\r
1542 //\r
1543 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1544 if (ObjBinBuf != NULL) {\r
1545 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1546 }\r
1547 \r
1548 //\r
1549 // update bin buffer to package data buffer\r
1550 //\r
1551 if (mObjBinBuf != NULL) {\r
1552 delete mObjBinBuf;\r
1553 mObjBinBuf = ObjBinBuf;\r
1554 }\r
1555 \r
1556 mDelayEmit = FALSE;\r
1557}\r
1558\r
1559/*\r
1560 * The definition of CIfrObj's member function\r
1561 */\r
1562static struct {\r
1563 UINT8 mSize;\r
1564 UINT8 mScope;\r
1565} gOpcodeSizesScopeTable[] = {\r
1566 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1567 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1568 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1569 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1570 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1571 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1572 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1573 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1574 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1575 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1576 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1577 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1578 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1579 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1580 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1581 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1582 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1583 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1584 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1585 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
1586 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
1587 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1588 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1589 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1590 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1591 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1592 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1593 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1594 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1595 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1596 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1597 { 0, 0 }, // 0x1F\r
1598 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1599 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
1600 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
1601 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1602 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1603 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1604 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1605 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1606 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1607 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
1608 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
1609 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
1610 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
1611 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
1612 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
1613 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1614 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1615 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1616 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1617 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1618 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1619 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1620 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1621 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1622 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1623 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1624 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1625 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1626 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1627 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1628 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1629 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1630 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1631 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1632 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1633 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1634 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1635 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1636 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1637 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1638 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1639 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1640 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1641 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1642 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1643 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1644 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1645 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1646 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1647 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1648 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1649 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1650 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1651 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1652 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1653 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1654 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1655 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1656 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1657 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1658 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
1659 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
1660 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1661 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
1662 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
1663 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
1664 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
1665 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
1666};\r
1667\r
1668#ifdef CIFROBJ_DEUBG\r
1669static struct {\r
1670 CHAR8 *mIfrName;\r
1671} gIfrObjPrintDebugTable[] = {\r
1672 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1673 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1674 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1675 "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
1676 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
1677 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
1678 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
1679 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
1680 "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
1681 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1682 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1683 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1684 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1685 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1686 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
1687 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
1688 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF",\r
1689};\r
1690\r
1691VOID\r
1692CIFROBJ_DEBUG_PRINT (\r
1693 IN UINT8 OpCode\r
1694 )\r
1695{\r
1696 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1697}\r
1698#else\r
1699\r
1700#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1701\r
1702#endif\r
1703\r
1704BOOLEAN gCreateOp = TRUE;\r
1705\r
1706CIfrObj::CIfrObj (\r
1707 IN UINT8 OpCode,\r
1708 OUT CHAR8 **IfrObj,\r
1709 IN UINT8 ObjBinLen,\r
1710 IN BOOLEAN DelayEmit\r
1711 )\r
1712{\r
1713 mDelayEmit = DelayEmit;\r
1714 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1715 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1716 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1717 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1718\r
1719 if (IfrObj != NULL) {\r
1720 *IfrObj = mObjBinBuf;\r
1721 }\r
1722\r
1723 CIFROBJ_DEBUG_PRINT (OpCode);\r
1724}\r
1725\r
1726CIfrObj::~CIfrObj (\r
1727 VOID\r
1728 )\r
1729{\r
1730 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1731 _EMIT_PENDING_OBJ ();\r
1732 }\r
1733\r
1734 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1735}\r
1736\r
1737/*\r
1738 * The definition of CIfrObj's member function\r
1739 */\r
1740UINT8 gScopeCount = 0;\r
1741\r
1742CIfrOpHeader::CIfrOpHeader (\r
1743 IN UINT8 OpCode,\r
1744 IN VOID *StartAddr,\r
1745 IN UINT8 Length\r
1746 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1747{\r
1748 mHeader->OpCode = OpCode;\r
1749 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1750 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1751}\r
1752\r
1753CIfrOpHeader::CIfrOpHeader (\r
1754 IN CIfrOpHeader &OpHdr\r
1755 )\r
1756{\r
1757 mHeader = OpHdr.mHeader;\r
1758}\r
1759\r
1760UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r