]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
ShellBinPkg: Update binaries
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 The definition of CFormPkg's member function\r
4\r
4afd3d04 5Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "VfrFormPkg.h"\r
18\r
19/*\r
20 * The definition of CFormPkg's member function\r
21 */\r
22\r
23SPendingAssign::SPendingAssign (\r
24 IN CHAR8 *Key, \r
25 IN VOID *Addr, \r
26 IN UINT32 Len, \r
27 IN UINT32 LineNo,\r
52302d4d 28 IN CONST CHAR8 *Msg\r
30fdf114
LG
29 )\r
30{\r
31 mKey = NULL;\r
32 mAddr = Addr;\r
33 mLen = Len;\r
34 mFlag = PENDING;\r
35 mLineNo = LineNo;\r
36 mMsg = NULL;\r
37 mNext = NULL;\r
38 if (Key != NULL) {\r
39 mKey = new CHAR8[strlen (Key) + 1];\r
40 if (mKey != NULL) {\r
41 strcpy (mKey, Key);\r
42 }\r
43 }\r
44\r
45 if (Msg != NULL) {\r
46 mMsg = new CHAR8[strlen (Msg) + 1];\r
47 if (mMsg != NULL) {\r
48 strcpy (mMsg, Msg);\r
49 }\r
50 }\r
51}\r
52\r
53SPendingAssign::~SPendingAssign (\r
54 VOID\r
55 )\r
56{\r
57 if (mKey != NULL) {\r
58 delete mKey;\r
59 }\r
60 mAddr = NULL;\r
61 mLen = 0;\r
62 mLineNo = 0;\r
63 if (mMsg != NULL) {\r
64 delete mMsg;\r
65 }\r
66 mNext = NULL;\r
67}\r
68\r
69VOID\r
70SPendingAssign::SetAddrAndLen (\r
71 IN VOID *Addr, \r
72 IN UINT32 LineNo\r
73 )\r
74{\r
75 mAddr = Addr;\r
76 mLineNo = LineNo;\r
77}\r
78\r
79VOID\r
80SPendingAssign::AssignValue (\r
81 IN VOID *Addr, \r
82 IN UINT32 Len\r
83 )\r
84{\r
85 memcpy (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 = 4096\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
4afd3d04
LG
155SBufferNode *\r
156CFormPkg::CreateNewNode (\r
157 VOID\r
158 )\r
159{\r
160 SBufferNode *Node;\r
161\r
162 Node = new SBufferNode;\r
163 if (Node == NULL) {\r
164 return NULL;\r
165 }\r
166\r
167 Node->mBufferStart = new CHAR8[mBufferSize];\r
168 if (Node->mBufferStart == NULL) {\r
169 delete Node;\r
170 return NULL;\r
171 } else {\r
172 memset (Node->mBufferStart, 0, mBufferSize);\r
173 Node->mBufferEnd = Node->mBufferStart + mBufferSize;\r
174 Node->mBufferFree = Node->mBufferStart;\r
175 Node->mNext = NULL;\r
176 }\r
177\r
178 return Node;\r
179}\r
180\r
30fdf114
LG
181CHAR8 *\r
182CFormPkg::IfrBinBufferGet (\r
183 IN UINT32 Len\r
184 )\r
185{\r
4afd3d04
LG
186 CHAR8 *BinBuffer = NULL;\r
187 SBufferNode *Node = NULL;\r
30fdf114
LG
188\r
189 if ((Len == 0) || (Len > mBufferSize)) {\r
190 return NULL;\r
191 }\r
192\r
193 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
194 BinBuffer = mCurrBufferNode->mBufferFree;\r
195 mCurrBufferNode->mBufferFree += Len;\r
196 } else {\r
4afd3d04 197 Node = CreateNewNode ();\r
30fdf114
LG
198 if (Node == NULL) {\r
199 return NULL;\r
200 }\r
201\r
30fdf114
LG
202 if (mBufferNodeQueueTail == NULL) {\r
203 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
204 } else {\r
205 mBufferNodeQueueTail->mNext = Node;\r
206 mBufferNodeQueueTail = Node;\r
207 }\r
208 mCurrBufferNode = Node;\r
209\r
210 //\r
211 // Now try again.\r
212 //\r
213 BinBuffer = mCurrBufferNode->mBufferFree;\r
214 mCurrBufferNode->mBufferFree += Len;\r
215 }\r
216\r
217 mPkgLength += Len;\r
218\r
219 return BinBuffer;\r
220}\r
221\r
222inline\r
223UINT32\r
224CFormPkg::GetPkgLength (\r
225 VOID\r
226 )\r
227{\r
228 return mPkgLength;\r
229}\r
230\r
231VOID\r
232CFormPkg::Open (\r
233 VOID\r
234 )\r
235{\r
236 mReadBufferNode = mBufferNodeQueueHead;\r
237 mReadBufferOffset = 0;\r
238}\r
239\r
240VOID\r
241CFormPkg::Close (\r
242 VOID\r
243 )\r
244{\r
245 mReadBufferNode = NULL;\r
246 mReadBufferOffset = 0;\r
247}\r
248\r
249UINT32\r
250CFormPkg::Read (\r
251 IN CHAR8 *Buffer, \r
252 IN UINT32 Size\r
253 )\r
254{\r
255 UINT32 Index;\r
256\r
257 if ((Size == 0) || (Buffer == NULL)) {\r
258 return 0;\r
259 }\r
260\r
261 if (mReadBufferNode == NULL) {\r
4afd3d04 262 return 0;\r
30fdf114
LG
263 }\r
264\r
265 for (Index = 0; Index < Size; Index++) {\r
266 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
267 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
268 } else {\r
269 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
270 return Index;\r
271 } else {\r
272 mReadBufferOffset = 0;\r
4afd3d04 273 Index --;\r
30fdf114
LG
274 }\r
275 }\r
276 }\r
277\r
278 return Size;\r
279}\r
280\r
281EFI_VFR_RETURN_CODE\r
282CFormPkg::BuildPkgHdr (\r
283 OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
284 )\r
285{\r
286 if (PkgHdr == NULL) {\r
287 return VFR_RETURN_FATAL_ERROR;\r
288 }\r
289\r
290 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
291 return VFR_RETURN_OUT_FOR_RESOURCES;\r
292 }\r
293\r
294 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
295 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
296\r
297 return VFR_RETURN_SUCCESS;\r
298}\r
299\r
300EFI_VFR_RETURN_CODE\r
301CFormPkg::BuildPkg (\r
302 OUT PACKAGE_DATA &TBuffer\r
303 )\r
304{\r
305 \r
306 CHAR8 *Temp;\r
307 UINT32 Size;\r
308 CHAR8 Buffer[1024];\r
309\r
310 if (TBuffer.Buffer != NULL) {\r
311 delete TBuffer.Buffer;\r
312 }\r
313\r
314 TBuffer.Size = mPkgLength;\r
315 TBuffer.Buffer = NULL;\r
316 if (TBuffer.Size != 0) {\r
317 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
318 } else {\r
319 return VFR_RETURN_SUCCESS;\r
320 }\r
321\r
322 Temp = TBuffer.Buffer;\r
323 Open ();\r
324 while ((Size = Read (Buffer, 1024)) != 0) {\r
325 memcpy (Temp, Buffer, Size);\r
326 Temp += Size;\r
327 }\r
328 Close ();\r
329 return VFR_RETURN_SUCCESS;\r
330}\r
331\r
332\r
333EFI_VFR_RETURN_CODE\r
334CFormPkg::BuildPkg (\r
335 IN FILE *Output,\r
336 IN PACKAGE_DATA *PkgData\r
337 )\r
338{\r
339 EFI_VFR_RETURN_CODE Ret;\r
340 CHAR8 Buffer[1024];\r
341 UINT32 Size;\r
342 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
343\r
344 if (Output == NULL) {\r
345 return VFR_RETURN_FATAL_ERROR;\r
346 }\r
347\r
348 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
349 return Ret;\r
350 }\r
351 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
352 delete PkgHdr;\r
353 \r
354 if (PkgData == NULL) {\r
355 Open ();\r
356 while ((Size = Read (Buffer, 1024)) != 0) {\r
357 fwrite (Buffer, Size, 1, Output);\r
358 }\r
359 Close ();\r
360 } else {\r
361 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);\r
362 }\r
363\r
364 return VFR_RETURN_SUCCESS;\r
365}\r
366\r
367VOID\r
368CFormPkg::_WRITE_PKG_LINE (\r
52302d4d
LG
369 IN FILE *pFile,\r
370 IN UINT32 LineBytes,\r
371 IN CONST CHAR8 *LineHeader,\r
372 IN CHAR8 *BlkBuf,\r
373 IN UINT32 BlkSize\r
30fdf114
LG
374 )\r
375{\r
376 UINT32 Index;\r
377\r
378 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
379 return;\r
380 }\r
381\r
382 for (Index = 0; Index < BlkSize; Index++) {\r
383 if ((Index % LineBytes) == 0) {\r
384 fprintf (pFile, "\n%s", LineHeader);\r
385 }\r
386 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
387 }\r
388}\r
389\r
390VOID\r
391CFormPkg::_WRITE_PKG_END (\r
52302d4d
LG
392 IN FILE *pFile,\r
393 IN UINT32 LineBytes,\r
394 IN CONST CHAR8 *LineHeader,\r
395 IN CHAR8 *BlkBuf,\r
396 IN UINT32 BlkSize\r
30fdf114
LG
397 )\r
398{\r
399 UINT32 Index;\r
400\r
401 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
402 return;\r
403 }\r
404\r
405 for (Index = 0; Index < BlkSize - 1; Index++) {\r
406 if ((Index % LineBytes) == 0) {\r
407 fprintf (pFile, "\n%s", LineHeader);\r
408 }\r
409 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
410 }\r
411\r
412 if ((Index % LineBytes) == 0) {\r
413 fprintf (pFile, "\n%s", LineHeader);\r
414 }\r
415 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
416}\r
417\r
418#define BYTES_PRE_LINE 0x10\r
4afd3d04
LG
419UINT32 gAdjustOpcodeOffset = 0;\r
420BOOLEAN gNeedAdjustOpcode = FALSE;\r
421UINT32 gAdjustOpcodeLen = 0;\r
30fdf114
LG
422\r
423EFI_VFR_RETURN_CODE \r
424CFormPkg::GenCFile (\r
425 IN CHAR8 *BaseName,\r
426 IN FILE *pFile,\r
427 IN PACKAGE_DATA *PkgData\r
428 )\r
429{\r
430 EFI_VFR_RETURN_CODE Ret;\r
431 CHAR8 Buffer[BYTES_PRE_LINE * 8];\r
432 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
433 UINT32 PkgLength = 0;\r
434 UINT32 ReadSize = 0;\r
435\r
436 if ((BaseName == NULL) || (pFile == NULL)) {\r
437 return VFR_RETURN_FATAL_ERROR;\r
438 }\r
439\r
440 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
441\r
442 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
443 return Ret;\r
444 }\r
445\r
446 //\r
447 // For framework vfr file, the extension framework header will be added.\r
448 //\r
449 if (VfrCompatibleMode) {\r
450 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
451 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
452 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
453 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
454 PkgLength = 3;\r
455 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16)); \r
456 } else {\r
457 fprintf (pFile, " // ARRAY LENGTH\n");\r
458 PkgLength = PkgHdr->Length + sizeof (UINT32);\r
459 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
460 }\r
461\r
462 fprintf (pFile, "\n\n // PACKAGE HEADER\n");\r
463 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
464 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
465\r
466 fprintf (pFile, "\n\n // PACKAGE DATA\n");\r
467 \r
468 if (PkgData == NULL) {\r
469 Open ();\r
470 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
471 PkgLength += ReadSize;\r
472 if (PkgLength < PkgHdr->Length) {\r
473 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
474 } else {\r
475 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
476 }\r
477 }\r
478 Close ();\r
479 } else {\r
480 if (PkgData->Size % BYTES_PRE_LINE != 0) {\r
481 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);\r
482 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
483 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);\r
484 } else {\r
485 PkgLength = PkgData->Size - BYTES_PRE_LINE;\r
486 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
487 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);\r
488 }\r
489 }\r
490\r
491 delete PkgHdr;\r
492 fprintf (pFile, "\n};\n");\r
493\r
494 return VFR_RETURN_SUCCESS;\r
495}\r
496\r
497EFI_VFR_RETURN_CODE\r
498CFormPkg::AssignPending (\r
499 IN CHAR8 *Key, \r
500 IN VOID *ValAddr, \r
501 IN UINT32 ValLen,\r
502 IN UINT32 LineNo,\r
52302d4d 503 IN CONST CHAR8 *Msg\r
30fdf114
LG
504 )\r
505{\r
506 SPendingAssign *pNew;\r
507\r
508 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);\r
509 if (pNew == NULL) {\r
510 return VFR_RETURN_OUT_FOR_RESOURCES;\r
511 }\r
512\r
513 pNew->mNext = PendingAssignList;\r
514 PendingAssignList = pNew;\r
515 return VFR_RETURN_SUCCESS;\r
516}\r
517\r
518VOID\r
519CFormPkg::DoPendingAssign (\r
520 IN CHAR8 *Key, \r
521 IN VOID *ValAddr, \r
522 IN UINT32 ValLen\r
523 )\r
524{\r
525 SPendingAssign *pNode;\r
526\r
527 if ((Key == NULL) || (ValAddr == NULL)) {\r
528 return;\r
529 }\r
530\r
531 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
532 if (strcmp (pNode->mKey, Key) == 0) {\r
533 pNode->AssignValue (ValAddr, ValLen);\r
534 }\r
535 }\r
536}\r
537\r
538bool\r
539CFormPkg::HavePendingUnassigned (\r
540 VOID\r
541 )\r
542{\r
543 SPendingAssign *pNode;\r
544\r
545 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
546 if (pNode->mFlag == PENDING) {\r
547 return TRUE;\r
548 }\r
549 }\r
550\r
551 return FALSE;\r
552}\r
553\r
554VOID\r
555CFormPkg::PendingAssignPrintAll (\r
556 VOID\r
557 )\r
558{\r
559 SPendingAssign *pNode;\r
560\r
561 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
562 if (pNode->mFlag == PENDING) {\r
563 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);\r
564 }\r
565 }\r
566}\r
567\r
4afd3d04
LG
568SBufferNode *\r
569CFormPkg::GetBinBufferNodeForAddr (\r
570 IN CHAR8 *BinBuffAddr\r
571 )\r
572{\r
573 SBufferNode *TmpNode;\r
574\r
575 TmpNode = mBufferNodeQueueHead;\r
576\r
577 while (TmpNode != NULL) {\r
578 if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {\r
579 return TmpNode;\r
580 }\r
581\r
582 TmpNode = TmpNode->mNext;\r
583 }\r
584\r
585 return NULL;\r
586}\r
587\r
588SBufferNode *\r
589CFormPkg::GetNodeBefore(\r
590 IN SBufferNode *CurrentNode\r
591 )\r
592{\r
593 SBufferNode *FirstNode = mBufferNodeQueueHead;\r
594 SBufferNode *LastNode = mBufferNodeQueueHead;\r
595\r
596 while (FirstNode != NULL) {\r
597 if (FirstNode == CurrentNode) {\r
598 break;\r
599 }\r
600\r
601 LastNode = FirstNode;\r
602 FirstNode = FirstNode->mNext;\r
603 }\r
604\r
605 if (FirstNode == NULL) {\r
606 LastNode = NULL;\r
607 }\r
608\r
609 return LastNode;\r
610}\r
611\r
612EFI_VFR_RETURN_CODE\r
613CFormPkg::InsertNodeBefore(\r
614 IN SBufferNode *CurrentNode,\r
615 IN SBufferNode *NewNode\r
616 )\r
617{\r
618 SBufferNode *LastNode = GetNodeBefore (CurrentNode);\r
619\r
620 if (LastNode == NULL) {\r
621 return VFR_RETURN_MISMATCHED;\r
622 }\r
623\r
624 NewNode->mNext = LastNode->mNext;\r
625 LastNode->mNext = NewNode;\r
626\r
627 return VFR_RETURN_SUCCESS;\r
628}\r
629\r
630CHAR8 *\r
631CFormPkg::GetBufAddrBaseOnOffset (\r
632 IN UINT32 Offset\r
633 )\r
634{\r
635 SBufferNode *TmpNode;\r
636 UINT32 TotalBufLen;\r
637 UINT32 CurrentBufLen;\r
638\r
639 TotalBufLen = 0;\r
640\r
641 for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {\r
642 CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;\r
643 if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {\r
644 return TmpNode->mBufferStart + (Offset - TotalBufLen);\r
645 }\r
646\r
647 TotalBufLen += CurrentBufLen;\r
648 }\r
649\r
650 return NULL;\r
651}\r
652\r
653EFI_VFR_RETURN_CODE\r
654CFormPkg::AdjustDynamicInsertOpcode (\r
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 memcpy (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 memcpy (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
30fdf114
LG
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
4afd3d04
LG
796 IN UINT32 LineNo,\r
797 OUT CHAR8 **InsertOpcodeAddr\r
30fdf114
LG
798 )\r
799{\r
800 SPendingAssign *pNode;\r
801 CHAR8 *VarStr;\r
802 UINT32 ArrayIdx;\r
803 CHAR8 FName[MAX_NAME_LEN];\r
b36d134f
LG
804 CHAR8 *SName;\r
805 CHAR8 *NewStr;\r
4afd3d04 806 UINT32 ShrinkSize;\r
30fdf114
LG
807 EFI_VFR_RETURN_CODE ReturnCode;\r
808 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
4afd3d04 809 EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;\r
30fdf114 810\r
b36d134f
LG
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
4afd3d04 817 *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
b36d134f
LG
818 \r
819 //TrueOpcode\r
820 CIfrTrue TObj (LineNo);\r
821\r
822 // Declare Numeric qeustion for each undefined question.\r
30fdf114
LG
823 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
824 if (pNode->mFlag == PENDING) {\r
30fdf114
LG
825 CIfrNumeric CNObj;\r
826 EFI_VARSTORE_INFO Info; \r
4afd3d04 827 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
30fdf114
LG
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
4afd3d04 857 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
30fdf114
LG
858 if (ReturnCode == VFR_RETURN_UNDEFINED) {\r
859 lCVfrDataStorage.DeclareBufferVarStore (\r
860 FName, \r
861 LocalFormSetGuid, \r
862 &lCVfrVarDataTypeDB, \r
863 FName,\r
864 EFI_VARSTORE_ID_INVALID,\r
865 FALSE\r
866 );\r
4afd3d04 867 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId, LocalFormSetGuid); \r
30fdf114
LG
868 }\r
869 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
870 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
871 return ReturnCode;\r
872 }\r
4afd3d04 873 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
30fdf114
LG
874\r
875 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
876 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
877 } else {\r
878 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
879 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
880 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
881 VarStr = pNode->mKey;\r
b36d134f 882 //convert VarStr with store name to VarStr with structure name\r
4afd3d04 883 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
b36d134f
LG
884 if (ReturnCode == VFR_RETURN_SUCCESS) {\r
885 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
886 NewStr[0] = '\0';\r
887 strcpy (NewStr, SName);\r
888 strcat (NewStr, VarStr + strlen (FName));\r
889 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
890 delete NewStr;\r
891 }\r
30fdf114
LG
892 } else {\r
893 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
894 }\r
895 }\r
896 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
897 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
898 return ReturnCode;\r
899 }\r
900\r
901 CNObj.SetQuestionId (QId);\r
902 CNObj.SetVarStoreInfo (&Info);\r
0d2711a6
LG
903 //\r
904 // Numeric doesn't support BOOLEAN data type. \r
905 // BOOLEAN type has the same data size to UINT8. \r
906 //\r
907 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
908 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
909 }\r
30fdf114 910 CNObj.SetFlags (0, Info.mVarType);\r
2bcc713e
LG
911 //\r
912 // Use maximum value not to limit the vaild value for the undefined question.\r
913 //\r
914 switch (Info.mVarType) {\r
915 case EFI_IFR_TYPE_NUM_SIZE_64:\r
916 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
4afd3d04 917 ShrinkSize = 0;\r
2bcc713e
LG
918 break;\r
919 case EFI_IFR_TYPE_NUM_SIZE_32:\r
920 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
4afd3d04 921 ShrinkSize = 12;\r
2bcc713e
LG
922 break;\r
923 case EFI_IFR_TYPE_NUM_SIZE_16:\r
924 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
4afd3d04 925 ShrinkSize = 18;\r
2bcc713e
LG
926 break;\r
927 case EFI_IFR_TYPE_NUM_SIZE_8:\r
928 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
4afd3d04 929 ShrinkSize = 21;\r
2bcc713e
LG
930 break;\r
931 default:\r
932 break;\r
933 }\r
4afd3d04 934 CNObj.ShrinkBinSize (ShrinkSize);\r
30fdf114
LG
935\r
936 //\r
937 // For undefined Efi VarStore type question\r
938 // Append the extended guided opcode to contain VarName\r
939 //\r
b36d134f 940 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
30fdf114
LG
941 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
942 CVNObj.SetLineNo (LineNo);\r
943 }\r
4afd3d04 944\r
30fdf114
LG
945 //\r
946 // End for Numeric\r
947 //\r
948 CIfrEnd CEObj; \r
949 CEObj.SetLineNo (LineNo);\r
30fdf114
LG
950 }\r
951 }\r
b36d134f
LG
952\r
953 //\r
954 // End for DisableIf\r
955 //\r
956 CIfrEnd SEObj;\r
957 SEObj.SetLineNo (LineNo);\r
958\r
30fdf114
LG
959 return VFR_RETURN_SUCCESS;\r
960}\r
961\r
962CFormPkg gCFormPkg;\r
963\r
964SIfrRecord::SIfrRecord (\r
965 VOID\r
966 )\r
967{\r
968 mIfrBinBuf = NULL;\r
969 mBinBufLen = 0;\r
970 mLineNo = 0xFFFFFFFF;\r
971 mOffset = 0xFFFFFFFF;\r
972 mNext = NULL;\r
973}\r
974\r
975SIfrRecord::~SIfrRecord (\r
976 VOID\r
977 )\r
978{\r
979 if (mIfrBinBuf != NULL) {\r
980 //delete mIfrBinBuf;\r
981 mIfrBinBuf = NULL;\r
982 }\r
983 mLineNo = 0xFFFFFFFF;\r
984 mOffset = 0xFFFFFFFF;\r
985 mBinBufLen = 0;\r
986 mNext = NULL;\r
987}\r
988\r
989CIfrRecordInfoDB::CIfrRecordInfoDB (\r
990 VOID\r
991 )\r
992{\r
993 mSwitch = TRUE;\r
994 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
995 mIfrRecordListHead = NULL;\r
996 mIfrRecordListTail = NULL;\r
997}\r
998\r
999CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
1000 VOID\r
1001 )\r
1002{\r
1003 SIfrRecord *pNode;\r
1004\r
1005 while (mIfrRecordListHead != NULL) {\r
1006 pNode = mIfrRecordListHead;\r
1007 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
1008 delete pNode;\r
1009 }\r
1010}\r
1011\r
1012SIfrRecord *\r
1013CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
1014 IN UINT32 RecordIdx\r
1015 )\r
1016{\r
1017 UINT32 Idx;\r
1018 SIfrRecord *pNode = NULL;\r
1019\r
1020 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
1021 return NULL;\r
1022 }\r
1023\r
1024 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
1025 (Idx != RecordIdx) && (pNode != NULL);\r
1026 Idx++, pNode = pNode->mNext)\r
1027 ;\r
1028\r
1029 return pNode;\r
1030}\r
1031\r
1032UINT32\r
1033CIfrRecordInfoDB::IfrRecordRegister (\r
1034 IN UINT32 LineNo,\r
1035 IN CHAR8 *IfrBinBuf,\r
1036 IN UINT8 BinBufLen,\r
1037 IN UINT32 Offset\r
1038 )\r
1039{\r
1040 SIfrRecord *pNew;\r
1041\r
1042 if (mSwitch == FALSE) {\r
1043 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1044 }\r
1045\r
1046 if ((pNew = new SIfrRecord) == NULL) {\r
1047 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1048 }\r
1049\r
1050 if (mIfrRecordListHead == NULL) {\r
1051 mIfrRecordListHead = pNew;\r
1052 mIfrRecordListTail = pNew;\r
1053 } else {\r
1054 mIfrRecordListTail->mNext = pNew;\r
1055 mIfrRecordListTail = pNew;\r
1056 }\r
1057 mRecordCount++;\r
1058\r
1059 return mRecordCount;\r
1060}\r
1061\r
1062VOID\r
1063CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
1064 IN UINT32 RecordIdx,\r
1065 IN UINT32 LineNo,\r
1066 IN CHAR8 *BinBuf,\r
1067 IN UINT8 BinBufLen,\r
1068 IN UINT32 Offset\r
1069 )\r
1070{\r
1071 SIfrRecord *pNode;\r
fd171542 1072 SIfrRecord *Prev;\r
30fdf114
LG
1073\r
1074 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
1075 return;\r
1076 }\r
1077\r
fd171542 1078 if (LineNo == 0) {\r
1079 //\r
1080 // Line number is not specified explicitly, try to use line number of previous opcode\r
1081 //\r
1082 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
1083 if (Prev != NULL) {\r
1084 LineNo = Prev->mLineNo;\r
1085 }\r
1086 }\r
1087\r
30fdf114
LG
1088 pNode->mLineNo = LineNo;\r
1089 pNode->mOffset = Offset;\r
1090 pNode->mBinBufLen = BinBufLen;\r
1091 pNode->mIfrBinBuf = BinBuf;\r
1092\r
1093}\r
1094\r
1095VOID\r
1096CIfrRecordInfoDB::IfrRecordOutput (\r
1097 OUT PACKAGE_DATA &TBuffer\r
1098 )\r
1099{\r
1100 CHAR8 *Temp;\r
1101 SIfrRecord *pNode; \r
1102\r
1103 if (TBuffer.Buffer != NULL) {\r
1104 delete TBuffer.Buffer;\r
1105 }\r
1106\r
1107 TBuffer.Size = 0;\r
1108 TBuffer.Buffer = NULL;\r
1109\r
1110\r
1111 if (mSwitch == FALSE) {\r
1112 return;\r
1113 } \r
1114 \r
1115 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1116 TBuffer.Size += pNode->mBinBufLen;\r
1117 }\r
1118 \r
1119 if (TBuffer.Size != 0) {\r
1120 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
1121 } else {\r
1122 return;\r
1123 }\r
1124 \r
1125 Temp = TBuffer.Buffer;\r
1126\r
1127 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1128 if (pNode->mIfrBinBuf != NULL) {\r
1129 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
1130 Temp += pNode->mBinBufLen;\r
1131 }\r
1132 }\r
1133\r
1134 return; \r
1135} \r
1136\r
1137VOID\r
1138CIfrRecordInfoDB::IfrRecordOutput (\r
1139 IN FILE *File,\r
1140 IN UINT32 LineNo\r
1141 )\r
1142{\r
1143 SIfrRecord *pNode;\r
1144 UINT8 Index;\r
1145 UINT32 TotalSize;\r
1146\r
1147 if (mSwitch == FALSE) {\r
1148 return;\r
1149 }\r
1150\r
1151 if (File == NULL) {\r
1152 return;\r
1153 }\r
1154\r
1155 TotalSize = 0;\r
1156\r
1157 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1158 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
1159 fprintf (File, ">%08X: ", pNode->mOffset);\r
1160 TotalSize += pNode->mBinBufLen;\r
1161 if (pNode->mIfrBinBuf != NULL) {\r
1162 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
1163 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
1164 }\r
1165 }\r
1166 fprintf (File, "\n");\r
1167 }\r
1168 }\r
1169 \r
1170 if (LineNo == 0) {\r
1171 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
1172 }\r
1173}\r
1174\r
1175//\r
1176// for framework vfr file\r
1177// adjust opcode sequence for uefi IFR format\r
1178// adjust inconsistent and varstore into the right position.\r
1179//\r
1180BOOLEAN\r
1181CIfrRecordInfoDB::CheckQuestionOpCode (\r
1182 IN UINT8 OpCode\r
1183 )\r
1184{\r
1185 switch (OpCode) {\r
1186 case EFI_IFR_CHECKBOX_OP:\r
1187 case EFI_IFR_NUMERIC_OP:\r
1188 case EFI_IFR_PASSWORD_OP:\r
1189 case EFI_IFR_ONE_OF_OP:\r
1190 case EFI_IFR_ACTION_OP:\r
1191 case EFI_IFR_STRING_OP:\r
1192 case EFI_IFR_DATE_OP:\r
1193 case EFI_IFR_TIME_OP:\r
1194 case EFI_IFR_ORDERED_LIST_OP:\r
1195 return TRUE;\r
1196 default:\r
1197 return FALSE;\r
1198 }\r
1199}\r
1200\r
1201BOOLEAN\r
1202CIfrRecordInfoDB::CheckIdOpCode (\r
1203 IN UINT8 OpCode\r
1204 )\r
1205{\r
1206 switch (OpCode) {\r
1207 case EFI_IFR_EQ_ID_VAL_OP:\r
1208 case EFI_IFR_EQ_ID_ID_OP:\r
64b2609f 1209 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
30fdf114
LG
1210 case EFI_IFR_QUESTION_REF1_OP:\r
1211 return TRUE;\r
1212 default:\r
1213 return FALSE;\r
1214 }\r
1215} \r
1216\r
1217EFI_QUESTION_ID\r
1218CIfrRecordInfoDB::GetOpcodeQuestionId (\r
1219 IN EFI_IFR_OP_HEADER *OpHead\r
1220 )\r
1221{\r
1222 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
1223 \r
1224 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
1225 \r
1226 return QuestionHead->QuestionId;\r
1227}\r
1228\r
4afd3d04
LG
1229SIfrRecord *\r
1230CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
1231 IN UINT32 Offset\r
1232 )\r
1233{\r
1234 SIfrRecord *pNode = NULL;\r
1235\r
1236 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1237 if (pNode->mOffset == Offset) {\r
1238 return pNode;\r
1239 }\r
1240 }\r
1241\r
1242 return pNode;\r
1243}\r
1244\r
1245/*\r
1246 Add just the op code position.\r
1247\r
1248 From\r
1249 \r
1250 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |\r
1251 \r
1252 To\r
1253 \r
1254 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |\r
1255\r
1256*/\r
1257BOOLEAN\r
1258CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
1259 VOID\r
1260 )\r
1261{\r
1262 UINT32 OpcodeOffset;\r
1263 SIfrRecord *pNode, *pPreNode;\r
1264 SIfrRecord *pStartNode, *pNodeBeforeStart;\r
1265 SIfrRecord *pEndNode;\r
1266 \r
1267 pStartNode = NULL;\r
1268 pEndNode = NULL;\r
1269 OpcodeOffset = 0;\r
1270\r
1271 //\r
1272 // Base on the offset info to get the node.\r
1273 //\r
1274 for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {\r
1275 if (OpcodeOffset == gAdjustOpcodeOffset) {\r
1276 pStartNode = pNode;\r
1277 pNodeBeforeStart = pPreNode;\r
1278 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
1279 pEndNode = pPreNode;\r
1280 }\r
1281\r
1282 OpcodeOffset += pNode->mBinBufLen;\r
1283 }\r
1284\r
1285 //\r
1286 // Check the value.\r
1287 //\r
1288 if (pEndNode == NULL || pStartNode == NULL) {\r
1289 return FALSE;\r
1290 }\r
1291\r
1292 //\r
1293 // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
1294 //\r
1295 pNodeBeforeStart->mNext = pEndNode->mNext;\r
1296 pPreNode->mNext = pStartNode;\r
1297 pEndNode->mNext = mIfrRecordListTail;\r
1298\r
1299 return TRUE;\r
1300}\r
1301\r
1302VOID\r
1303CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
1304 VOID\r
1305 )\r
1306{\r
1307 UINT32 OpcodeOffset;\r
1308 SIfrRecord *pNode;\r
1309\r
1310 OpcodeOffset = 0;\r
1311 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1312 pNode->mOffset = OpcodeOffset;\r
1313 OpcodeOffset += pNode->mBinBufLen;\r
1314 }\r
1315}\r
1316\r
30fdf114
LG
1317EFI_VFR_RETURN_CODE\r
1318CIfrRecordInfoDB::IfrRecordAdjust (\r
1319 VOID\r
1320 )\r
1321{\r
1322 SIfrRecord *pNode, *preNode;\r
1323 SIfrRecord *uNode, *tNode;\r
1324 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
1325 EFI_QUESTION_ID QuestionId;\r
1326 UINT32 StackCount;\r
1327 UINT32 QuestionScope;\r
1328 UINT32 OpcodeOffset;\r
1329 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
1330 EFI_VFR_RETURN_CODE Status;\r
1331\r
1332 //\r
1333 // Init local variable\r
1334 //\r
1335 Status = VFR_RETURN_SUCCESS;\r
1336 pNode = mIfrRecordListHead;\r
1337 preNode = pNode;\r
1338 QuestionScope = 0;\r
1339 while (pNode != NULL) {\r
1340 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1341 \r
1342 //\r
1343 // make sure the inconsistent opcode in question scope\r
1344 //\r
1345 if (QuestionScope > 0) {\r
1346 QuestionScope += OpHead->Scope;\r
1347 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1348 QuestionScope --;\r
1349 }\r
1350 }\r
1351 \r
1352 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1353 QuestionScope = 1;\r
1354 }\r
1355 //\r
1356 // for the inconsistent opcode not in question scope, adjust it\r
1357 //\r
1358 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1359 //\r
1360 // for inconsistent opcode not in question scope\r
1361 //\r
1362\r
1363 //\r
1364 // Count inconsistent opcode Scope \r
1365 //\r
1366 StackCount = OpHead->Scope;\r
1367 QuestionId = EFI_QUESTION_ID_INVALID;\r
1368 tNode = pNode;\r
1369 while (tNode != NULL && StackCount > 0) {\r
1370 tNode = tNode->mNext;\r
1371 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1372 //\r
1373 // Calculate Scope Number\r
1374 //\r
1375 StackCount += tOpHead->Scope;\r
1376 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1377 StackCount --;\r
1378 }\r
1379 //\r
1380 // by IdEqual opcode to get QuestionId\r
1381 //\r
1382 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1383 CheckIdOpCode (tOpHead->OpCode)) {\r
1384 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1385 }\r
1386 }\r
1387 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1388 //\r
1389 // report error; not found\r
1390 //\r
1391 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1392 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1393 Status = VFR_RETURN_MISMATCHED;\r
1394 break;\r
1395 }\r
1396 //\r
1397 // extract inconsistent opcode list\r
1398 // pNode is Incosistent opcode, tNode is End Opcode\r
1399 //\r
1400 \r
1401 //\r
1402 // insert inconsistent opcode list into the right question scope by questionid\r
1403 //\r
1404 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1405 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1406 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1407 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1408 break;\r
1409 }\r
1410 }\r
1411 //\r
1412 // insert inconsistent opcode list and check LATE_CHECK flag\r
1413 //\r
1414 if (uNode != NULL) {\r
1415 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1416 //\r
1417 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1418 //\r
1419 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1420 }\r
1421 \r
1422 //\r
1423 // skip the default storage for Date and Time\r
1424 //\r
1425 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1426 uNode = uNode->mNext;\r
1427 }\r
1428\r
1429 preNode->mNext = tNode->mNext;\r
1430 tNode->mNext = uNode->mNext;\r
1431 uNode->mNext = pNode;\r
1432 //\r
1433 // reset pNode to head list, scan the whole list again.\r
1434 //\r
1435 pNode = mIfrRecordListHead;\r
1436 preNode = pNode;\r
1437 QuestionScope = 0;\r
1438 continue;\r
1439 } else {\r
1440 //\r
1441 // not found matched question id, report error\r
1442 //\r
1443 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1444 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1445 Status = VFR_RETURN_MISMATCHED;\r
1446 break;\r
1447 }\r
1448 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1449 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1450 //\r
1451 // for new added group of varstore opcode\r
1452 //\r
1453 tNode = pNode;\r
1454 while (tNode->mNext != NULL) {\r
1455 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1456 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1457 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1458 break; \r
1459 }\r
1460 tNode = tNode->mNext;\r
1461 }\r
1462\r
1463 if (tNode->mNext == NULL) {\r
1464 //\r
1465 // invalid IfrCode, IfrCode end by EndOpCode\r
1466 // \r
1467 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1468 Status = VFR_RETURN_MISMATCHED;\r
1469 break;\r
1470 }\r
1471 \r
1472 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1473 //\r
1474 // not new added varstore, which are not needed to be adjust.\r
1475 //\r
1476 preNode = tNode;\r
1477 pNode = tNode->mNext;\r
1478 continue; \r
1479 } else {\r
1480 //\r
1481 // move new added varstore opcode to the position befor form opcode \r
1482 // varstore opcode between pNode and tNode\r
1483 //\r
1484\r
1485 //\r
1486 // search form opcode from begin\r
1487 //\r
1488 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1489 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1490 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1491 break;\r
1492 }\r
1493 }\r
1494 //\r
1495 // Insert varstore opcode beform form opcode if form opcode is found\r
1496 //\r
1497 if (uNode->mNext != NULL) {\r
1498 preNode->mNext = tNode->mNext;\r
1499 tNode->mNext = uNode->mNext;\r
1500 uNode->mNext = pNode;\r
1501 //\r
1502 // reset pNode to head list, scan the whole list again.\r
1503 //\r
1504 pNode = mIfrRecordListHead;\r
1505 preNode = pNode;\r
1506 QuestionScope = 0;\r
1507 continue;\r
1508 } else {\r
1509 //\r
1510 // not found form, continue scan IfrRecord list\r
1511 //\r
1512 preNode = tNode;\r
1513 pNode = tNode->mNext;\r
1514 continue;\r
1515 }\r
1516 }\r
1517 }\r
1518 //\r
1519 // next node\r
1520 //\r
1521 preNode = pNode;\r
1522 pNode = pNode->mNext; \r
1523 }\r
1524 \r
1525 //\r
1526 // Update Ifr Opcode Offset\r
1527 //\r
1528 if (Status == VFR_RETURN_SUCCESS) {\r
4afd3d04 1529 IfrAdjustOffsetForRecord ();\r
30fdf114
LG
1530 }\r
1531 return Status;\r
1532}\r
1533\r
1534CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1535\r
1536VOID\r
1537CIfrObj::_EMIT_PENDING_OBJ (\r
1538 VOID\r
1539 )\r
1540{\r
1541 CHAR8 *ObjBinBuf = NULL;\r
1542 \r
1543 //\r
1544 // do nothing\r
1545 //\r
1546 if (!mDelayEmit || !gCreateOp) {\r
1547 return;\r
1548 }\r
1549\r
1550 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1551 //\r
1552 // update data buffer to package data\r
1553 //\r
1554 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1555 if (ObjBinBuf != NULL) {\r
1556 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1557 }\r
1558 \r
1559 //\r
1560 // update bin buffer to package data buffer\r
1561 //\r
1562 if (mObjBinBuf != NULL) {\r
1563 delete mObjBinBuf;\r
1564 mObjBinBuf = ObjBinBuf;\r
1565 }\r
1566 \r
1567 mDelayEmit = FALSE;\r
1568}\r
1569\r
1570/*\r
1571 * The definition of CIfrObj's member function\r
1572 */\r
1573static struct {\r
1574 UINT8 mSize;\r
1575 UINT8 mScope;\r
1576} gOpcodeSizesScopeTable[] = {\r
1577 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1578 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1579 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1580 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1581 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1582 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1583 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1584 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1585 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1586 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1587 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1588 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1589 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1590 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1591 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1592 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1593 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1594 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1595 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1596 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
b303ea72 1597 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
1598 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1599 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1600 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1601 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1602 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1603 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1604 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1605 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1606 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1607 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1608 { 0, 0 }, // 0x1F\r
1609 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1610 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
52302d4d 1611 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
1612 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1613 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1614 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1615 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1616 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1617 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1618 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
52302d4d
LG
1619 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
1620 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
1621 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
1622 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
1623 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
30fdf114
LG
1624 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1625 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1626 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1627 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1628 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1629 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1630 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1631 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1632 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1633 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1634 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1635 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1636 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1637 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1638 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1639 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1640 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1641 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1642 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1643 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1644 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1645 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1646 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1647 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1648 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1649 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1650 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1651 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1652 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1653 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1654 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1655 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1656 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1657 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1658 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1659 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1660 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1661 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1662 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1663 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1664 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1665 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1666 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1667 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1668 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1669 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
52302d4d 1670 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
1671 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1672 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 1673 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
4afd3d04 1674 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
4234283c 1675 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
30fdf114
LG
1676};\r
1677\r
1678#ifdef CIFROBJ_DEUBG\r
1679static struct {\r
1680 CHAR8 *mIfrName;\r
1681} gIfrObjPrintDebugTable[] = {\r
1682 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1683 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1684 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1685 "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
1686 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
52302d4d 1687 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 1688 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 1689 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
1690 "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
1691 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1692 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1693 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1694 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1695 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1696 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
52302d4d 1697 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
4afd3d04 1698 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID",\r
30fdf114
LG
1699};\r
1700\r
1701VOID\r
1702CIFROBJ_DEBUG_PRINT (\r
1703 IN UINT8 OpCode\r
1704 )\r
1705{\r
1706 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1707}\r
1708#else\r
1709\r
1710#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1711\r
1712#endif\r
1713\r
52302d4d 1714BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
1715\r
1716CIfrObj::CIfrObj (\r
1717 IN UINT8 OpCode,\r
1718 OUT CHAR8 **IfrObj,\r
1719 IN UINT8 ObjBinLen,\r
1720 IN BOOLEAN DelayEmit\r
1721 )\r
1722{\r
1723 mDelayEmit = DelayEmit;\r
1724 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1725 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1726 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1727 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1728\r
1729 if (IfrObj != NULL) {\r
1730 *IfrObj = mObjBinBuf;\r
1731 }\r
1732\r
1733 CIFROBJ_DEBUG_PRINT (OpCode);\r
1734}\r
1735\r
1736CIfrObj::~CIfrObj (\r
1737 VOID\r
1738 )\r
1739{\r
1740 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1741 _EMIT_PENDING_OBJ ();\r
1742 }\r
1743\r
1744 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1745}\r
1746\r
1747/*\r
1748 * The definition of CIfrObj's member function\r
1749 */\r
1750UINT8 gScopeCount = 0;\r
1751\r
1752CIfrOpHeader::CIfrOpHeader (\r
1753 IN UINT8 OpCode,\r
1754 IN VOID *StartAddr,\r
1755 IN UINT8 Length\r
1756 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1757{\r
1758 mHeader->OpCode = OpCode;\r
1759 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1760 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1761}\r
1762\r
1763CIfrOpHeader::CIfrOpHeader (\r
1764 IN CIfrOpHeader &OpHdr\r
1765 )\r
1766{\r
1767 mHeader = OpHdr.mHeader;\r
1768}\r
1769\r
52302d4d 1770UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r