]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
MdeModulePkg: update comments for question.
[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
f51461c8 85 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));\r
30fdf114
LG
86 mFlag = ASSIGNED;\r
87}\r
88\r
89CHAR8 *\r
90SPendingAssign::GetKey (\r
91 VOID\r
92 )\r
93{\r
94 return mKey;\r
95}\r
96\r
97CFormPkg::CFormPkg (\r
ed395cfe 98 IN UINT32 BufferSize\r
30fdf114
LG
99 )\r
100{\r
101 CHAR8 *BufferStart;\r
102 CHAR8 *BufferEnd;\r
103 SBufferNode *Node;\r
104\r
105 mPkgLength = 0;\r
106 mBufferNodeQueueHead = NULL;\r
107 mCurrBufferNode = NULL;\r
108\r
109 Node = new SBufferNode;\r
110 if (Node == NULL) {\r
111 return ;\r
112 }\r
113 BufferStart = new CHAR8[BufferSize];\r
114 if (BufferStart == NULL) {\r
115 return;\r
116 }\r
117 BufferEnd = BufferStart + BufferSize;\r
118\r
119 memset (BufferStart, 0, BufferSize);\r
120 Node->mBufferStart = BufferStart;\r
121 Node->mBufferEnd = BufferEnd;\r
122 Node->mBufferFree = BufferStart;\r
123 Node->mNext = NULL;\r
124\r
125 mBufferSize = BufferSize;\r
126 mBufferNodeQueueHead = Node;\r
127 mBufferNodeQueueTail = Node;\r
128 mCurrBufferNode = Node;\r
129}\r
130\r
131CFormPkg::~CFormPkg ()\r
132{\r
133 SBufferNode *pBNode;\r
134 SPendingAssign *pPNode;\r
135\r
136 while (mBufferNodeQueueHead != NULL) {\r
137 pBNode = mBufferNodeQueueHead;\r
138 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
139 if (pBNode->mBufferStart != NULL) {\r
140 delete pBNode->mBufferStart;\r
141 delete pBNode;\r
142 }\r
143 }\r
144 mBufferNodeQueueTail = NULL;\r
145 mCurrBufferNode = NULL;\r
146\r
147 while (PendingAssignList != NULL) {\r
148 pPNode = PendingAssignList;\r
149 PendingAssignList = PendingAssignList->mNext;\r
150 delete pPNode;\r
151 }\r
152 PendingAssignList = NULL;\r
153}\r
154\r
4afd3d04
LG
155SBufferNode *\r
156CFormPkg::CreateNewNode (\r
157 VOID\r
158 )\r
159{\r
160 SBufferNode *Node;\r
161\r
162 Node = new SBufferNode;\r
163 if (Node == NULL) {\r
164 return NULL;\r
165 }\r
166\r
167 Node->mBufferStart = new CHAR8[mBufferSize];\r
168 if (Node->mBufferStart == NULL) {\r
169 delete Node;\r
170 return NULL;\r
171 } else {\r
172 memset (Node->mBufferStart, 0, mBufferSize);\r
173 Node->mBufferEnd = Node->mBufferStart + mBufferSize;\r
174 Node->mBufferFree = Node->mBufferStart;\r
175 Node->mNext = NULL;\r
176 }\r
177\r
178 return Node;\r
179}\r
180\r
30fdf114
LG
181CHAR8 *\r
182CFormPkg::IfrBinBufferGet (\r
183 IN UINT32 Len\r
184 )\r
185{\r
4afd3d04
LG
186 CHAR8 *BinBuffer = NULL;\r
187 SBufferNode *Node = NULL;\r
30fdf114
LG
188\r
189 if ((Len == 0) || (Len > mBufferSize)) {\r
190 return NULL;\r
191 }\r
192\r
193 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
194 BinBuffer = mCurrBufferNode->mBufferFree;\r
195 mCurrBufferNode->mBufferFree += Len;\r
196 } else {\r
4afd3d04 197 Node = CreateNewNode ();\r
30fdf114
LG
198 if (Node == NULL) {\r
199 return NULL;\r
200 }\r
201\r
30fdf114
LG
202 if (mBufferNodeQueueTail == NULL) {\r
203 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
204 } else {\r
205 mBufferNodeQueueTail->mNext = Node;\r
206 mBufferNodeQueueTail = Node;\r
207 }\r
208 mCurrBufferNode = Node;\r
209\r
210 //\r
211 // Now try again.\r
212 //\r
213 BinBuffer = mCurrBufferNode->mBufferFree;\r
214 mCurrBufferNode->mBufferFree += Len;\r
215 }\r
216\r
217 mPkgLength += Len;\r
218\r
219 return BinBuffer;\r
220}\r
221\r
222inline\r
223UINT32\r
224CFormPkg::GetPkgLength (\r
225 VOID\r
226 )\r
227{\r
228 return mPkgLength;\r
229}\r
230\r
231VOID\r
232CFormPkg::Open (\r
233 VOID\r
234 )\r
235{\r
236 mReadBufferNode = mBufferNodeQueueHead;\r
237 mReadBufferOffset = 0;\r
238}\r
239\r
240VOID\r
241CFormPkg::Close (\r
242 VOID\r
243 )\r
244{\r
245 mReadBufferNode = NULL;\r
246 mReadBufferOffset = 0;\r
247}\r
248\r
249UINT32\r
250CFormPkg::Read (\r
251 IN CHAR8 *Buffer, \r
252 IN UINT32 Size\r
253 )\r
254{\r
255 UINT32 Index;\r
256\r
257 if ((Size == 0) || (Buffer == NULL)) {\r
258 return 0;\r
259 }\r
260\r
261 if (mReadBufferNode == NULL) {\r
4afd3d04 262 return 0;\r
30fdf114
LG
263 }\r
264\r
265 for (Index = 0; Index < Size; Index++) {\r
266 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
267 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
268 } else {\r
269 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
270 return Index;\r
271 } else {\r
272 mReadBufferOffset = 0;\r
4afd3d04 273 Index --;\r
30fdf114
LG
274 }\r
275 }\r
276 }\r
277\r
278 return Size;\r
279}\r
280\r
281EFI_VFR_RETURN_CODE\r
282CFormPkg::BuildPkgHdr (\r
283 OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
284 )\r
285{\r
286 if (PkgHdr == NULL) {\r
287 return VFR_RETURN_FATAL_ERROR;\r
288 }\r
289\r
290 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
291 return VFR_RETURN_OUT_FOR_RESOURCES;\r
292 }\r
293\r
294 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
295 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
296\r
297 return VFR_RETURN_SUCCESS;\r
298}\r
299\r
300EFI_VFR_RETURN_CODE\r
301CFormPkg::BuildPkg (\r
302 OUT PACKAGE_DATA &TBuffer\r
303 )\r
304{\r
305 \r
306 CHAR8 *Temp;\r
307 UINT32 Size;\r
308 CHAR8 Buffer[1024];\r
309\r
310 if (TBuffer.Buffer != NULL) {\r
311 delete TBuffer.Buffer;\r
312 }\r
313\r
314 TBuffer.Size = mPkgLength;\r
315 TBuffer.Buffer = NULL;\r
316 if (TBuffer.Size != 0) {\r
317 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
318 } else {\r
319 return VFR_RETURN_SUCCESS;\r
320 }\r
321\r
322 Temp = TBuffer.Buffer;\r
323 Open ();\r
324 while ((Size = Read (Buffer, 1024)) != 0) {\r
325 memcpy (Temp, Buffer, Size);\r
326 Temp += Size;\r
327 }\r
328 Close ();\r
329 return VFR_RETURN_SUCCESS;\r
330}\r
331\r
332\r
333EFI_VFR_RETURN_CODE\r
334CFormPkg::BuildPkg (\r
335 IN FILE *Output,\r
336 IN PACKAGE_DATA *PkgData\r
337 )\r
338{\r
339 EFI_VFR_RETURN_CODE Ret;\r
340 CHAR8 Buffer[1024];\r
341 UINT32 Size;\r
342 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
343\r
344 if (Output == NULL) {\r
345 return VFR_RETURN_FATAL_ERROR;\r
346 }\r
347\r
348 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
349 return Ret;\r
350 }\r
351 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
352 delete PkgHdr;\r
353 \r
354 if (PkgData == NULL) {\r
355 Open ();\r
356 while ((Size = Read (Buffer, 1024)) != 0) {\r
357 fwrite (Buffer, Size, 1, Output);\r
358 }\r
359 Close ();\r
360 } else {\r
361 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);\r
362 }\r
363\r
364 return VFR_RETURN_SUCCESS;\r
365}\r
366\r
367VOID\r
368CFormPkg::_WRITE_PKG_LINE (\r
52302d4d
LG
369 IN FILE *pFile,\r
370 IN UINT32 LineBytes,\r
371 IN CONST CHAR8 *LineHeader,\r
372 IN CHAR8 *BlkBuf,\r
373 IN UINT32 BlkSize\r
30fdf114
LG
374 )\r
375{\r
376 UINT32 Index;\r
377\r
378 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
379 return;\r
380 }\r
381\r
382 for (Index = 0; Index < BlkSize; Index++) {\r
383 if ((Index % LineBytes) == 0) {\r
384 fprintf (pFile, "\n%s", LineHeader);\r
385 }\r
386 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
387 }\r
388}\r
389\r
390VOID\r
391CFormPkg::_WRITE_PKG_END (\r
52302d4d
LG
392 IN FILE *pFile,\r
393 IN UINT32 LineBytes,\r
394 IN CONST CHAR8 *LineHeader,\r
395 IN CHAR8 *BlkBuf,\r
396 IN UINT32 BlkSize\r
30fdf114
LG
397 )\r
398{\r
399 UINT32 Index;\r
400\r
401 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
402 return;\r
403 }\r
404\r
405 for (Index = 0; Index < BlkSize - 1; Index++) {\r
406 if ((Index % LineBytes) == 0) {\r
407 fprintf (pFile, "\n%s", LineHeader);\r
408 }\r
409 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
410 }\r
411\r
412 if ((Index % LineBytes) == 0) {\r
413 fprintf (pFile, "\n%s", LineHeader);\r
414 }\r
415 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
416}\r
417\r
418#define BYTES_PRE_LINE 0x10\r
4afd3d04
LG
419UINT32 gAdjustOpcodeOffset = 0;\r
420BOOLEAN gNeedAdjustOpcode = FALSE;\r
421UINT32 gAdjustOpcodeLen = 0;\r
30fdf114
LG
422\r
423EFI_VFR_RETURN_CODE \r
424CFormPkg::GenCFile (\r
425 IN CHAR8 *BaseName,\r
426 IN FILE *pFile,\r
427 IN PACKAGE_DATA *PkgData\r
428 )\r
429{\r
430 EFI_VFR_RETURN_CODE Ret;\r
431 CHAR8 Buffer[BYTES_PRE_LINE * 8];\r
432 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
433 UINT32 PkgLength = 0;\r
434 UINT32 ReadSize = 0;\r
435\r
436 if ((BaseName == NULL) || (pFile == NULL)) {\r
437 return VFR_RETURN_FATAL_ERROR;\r
438 }\r
439\r
440 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
441\r
442 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
443 return Ret;\r
444 }\r
445\r
446 //\r
447 // For framework vfr file, the extension framework header will be added.\r
448 //\r
449 if (VfrCompatibleMode) {\r
450 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
451 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
452 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
453 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
454 PkgLength = 3;\r
455 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16)); \r
456 } else {\r
457 fprintf (pFile, " // ARRAY LENGTH\n");\r
458 PkgLength = PkgHdr->Length + sizeof (UINT32);\r
459 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
460 }\r
461\r
462 fprintf (pFile, "\n\n // PACKAGE HEADER\n");\r
463 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
464 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
465\r
466 fprintf (pFile, "\n\n // PACKAGE DATA\n");\r
467 \r
468 if (PkgData == NULL) {\r
469 Open ();\r
470 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
471 PkgLength += ReadSize;\r
472 if (PkgLength < PkgHdr->Length) {\r
473 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
474 } else {\r
475 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
476 }\r
477 }\r
478 Close ();\r
479 } else {\r
480 if (PkgData->Size % BYTES_PRE_LINE != 0) {\r
481 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);\r
482 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
483 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);\r
484 } else {\r
485 PkgLength = PkgData->Size - BYTES_PRE_LINE;\r
486 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
487 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);\r
488 }\r
489 }\r
490\r
491 delete PkgHdr;\r
492 fprintf (pFile, "\n};\n");\r
493\r
494 return VFR_RETURN_SUCCESS;\r
495}\r
496\r
497EFI_VFR_RETURN_CODE\r
498CFormPkg::AssignPending (\r
499 IN CHAR8 *Key, \r
500 IN VOID *ValAddr, \r
501 IN UINT32 ValLen,\r
502 IN UINT32 LineNo,\r
52302d4d 503 IN CONST CHAR8 *Msg\r
30fdf114
LG
504 )\r
505{\r
506 SPendingAssign *pNew;\r
507\r
508 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);\r
509 if (pNew == NULL) {\r
510 return VFR_RETURN_OUT_FOR_RESOURCES;\r
511 }\r
512\r
513 pNew->mNext = PendingAssignList;\r
514 PendingAssignList = pNew;\r
515 return VFR_RETURN_SUCCESS;\r
516}\r
517\r
518VOID\r
519CFormPkg::DoPendingAssign (\r
520 IN CHAR8 *Key, \r
521 IN VOID *ValAddr, \r
522 IN UINT32 ValLen\r
523 )\r
524{\r
525 SPendingAssign *pNode;\r
526\r
527 if ((Key == NULL) || (ValAddr == NULL)) {\r
528 return;\r
529 }\r
530\r
531 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
532 if (strcmp (pNode->mKey, Key) == 0) {\r
533 pNode->AssignValue (ValAddr, ValLen);\r
534 }\r
535 }\r
536}\r
537\r
538bool\r
539CFormPkg::HavePendingUnassigned (\r
540 VOID\r
541 )\r
542{\r
543 SPendingAssign *pNode;\r
544\r
545 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
546 if (pNode->mFlag == PENDING) {\r
547 return TRUE;\r
548 }\r
549 }\r
550\r
551 return FALSE;\r
552}\r
553\r
554VOID\r
555CFormPkg::PendingAssignPrintAll (\r
556 VOID\r
557 )\r
558{\r
559 SPendingAssign *pNode;\r
560\r
561 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
562 if (pNode->mFlag == PENDING) {\r
563 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);\r
564 }\r
565 }\r
566}\r
567\r
4afd3d04
LG
568SBufferNode *\r
569CFormPkg::GetBinBufferNodeForAddr (\r
570 IN CHAR8 *BinBuffAddr\r
571 )\r
572{\r
573 SBufferNode *TmpNode;\r
574\r
575 TmpNode = mBufferNodeQueueHead;\r
576\r
577 while (TmpNode != NULL) {\r
578 if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {\r
579 return TmpNode;\r
580 }\r
581\r
582 TmpNode = TmpNode->mNext;\r
583 }\r
584\r
585 return NULL;\r
586}\r
587\r
588SBufferNode *\r
589CFormPkg::GetNodeBefore(\r
590 IN SBufferNode *CurrentNode\r
591 )\r
592{\r
593 SBufferNode *FirstNode = mBufferNodeQueueHead;\r
594 SBufferNode *LastNode = mBufferNodeQueueHead;\r
595\r
596 while (FirstNode != NULL) {\r
597 if (FirstNode == CurrentNode) {\r
598 break;\r
599 }\r
600\r
601 LastNode = FirstNode;\r
602 FirstNode = FirstNode->mNext;\r
603 }\r
604\r
605 if (FirstNode == NULL) {\r
606 LastNode = NULL;\r
607 }\r
608\r
609 return LastNode;\r
610}\r
611\r
612EFI_VFR_RETURN_CODE\r
613CFormPkg::InsertNodeBefore(\r
614 IN SBufferNode *CurrentNode,\r
615 IN SBufferNode *NewNode\r
616 )\r
617{\r
618 SBufferNode *LastNode = GetNodeBefore (CurrentNode);\r
619\r
620 if (LastNode == NULL) {\r
621 return VFR_RETURN_MISMATCHED;\r
622 }\r
623\r
624 NewNode->mNext = LastNode->mNext;\r
625 LastNode->mNext = NewNode;\r
626\r
627 return VFR_RETURN_SUCCESS;\r
628}\r
629\r
630CHAR8 *\r
631CFormPkg::GetBufAddrBaseOnOffset (\r
632 IN UINT32 Offset\r
633 )\r
634{\r
635 SBufferNode *TmpNode;\r
636 UINT32 TotalBufLen;\r
637 UINT32 CurrentBufLen;\r
638\r
639 TotalBufLen = 0;\r
640\r
641 for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {\r
642 CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;\r
643 if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {\r
644 return TmpNode->mBufferStart + (Offset - TotalBufLen);\r
645 }\r
646\r
647 TotalBufLen += CurrentBufLen;\r
648 }\r
649\r
650 return NULL;\r
651}\r
652\r
653EFI_VFR_RETURN_CODE\r
654CFormPkg::AdjustDynamicInsertOpcode (\r
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
f51461c8 688 memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
4afd3d04
LG
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
f51461c8 736 memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
4afd3d04
LG
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_SUCCESS) {\r
859 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
860 return ReturnCode;\r
861 }\r
4afd3d04 862 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
30fdf114
LG
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
b36d134f 871 //convert VarStr with store name to VarStr with structure name\r
4afd3d04 872 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
b36d134f
LG
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
30fdf114
LG
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
0d2711a6
LG
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
30fdf114 899 CNObj.SetFlags (0, Info.mVarType);\r
2bcc713e
LG
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
4afd3d04 906 ShrinkSize = 0;\r
2bcc713e
LG
907 break;\r
908 case EFI_IFR_TYPE_NUM_SIZE_32:\r
909 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
4afd3d04 910 ShrinkSize = 12;\r
2bcc713e
LG
911 break;\r
912 case EFI_IFR_TYPE_NUM_SIZE_16:\r
913 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
4afd3d04 914 ShrinkSize = 18;\r
2bcc713e
LG
915 break;\r
916 case EFI_IFR_TYPE_NUM_SIZE_8:\r
917 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
4afd3d04 918 ShrinkSize = 21;\r
2bcc713e
LG
919 break;\r
920 default:\r
921 break;\r
922 }\r
4afd3d04 923 CNObj.ShrinkBinSize (ShrinkSize);\r
30fdf114
LG
924\r
925 //\r
926 // For undefined Efi VarStore type question\r
927 // Append the extended guided opcode to contain VarName\r
928 //\r
b36d134f 929 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
30fdf114
LG
930 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
931 CVNObj.SetLineNo (LineNo);\r
932 }\r
4afd3d04 933\r
30fdf114
LG
934 //\r
935 // End for Numeric\r
936 //\r
937 CIfrEnd CEObj; \r
938 CEObj.SetLineNo (LineNo);\r
30fdf114
LG
939 }\r
940 }\r
b36d134f
LG
941\r
942 //\r
943 // End for DisableIf\r
944 //\r
945 CIfrEnd SEObj;\r
946 SEObj.SetLineNo (LineNo);\r
947\r
30fdf114
LG
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
fd171542 1061 SIfrRecord *Prev;\r
30fdf114
LG
1062\r
1063 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
1064 return;\r
1065 }\r
1066\r
fd171542 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
30fdf114
LG
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
64b2609f 1198 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
30fdf114
LG
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
4afd3d04
LG
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
30fdf114
LG
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
4afd3d04 1518 IfrAdjustOffsetForRecord ();\r
30fdf114
LG
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
f51461c8 1545 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
30fdf114
LG
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
b303ea72 1586 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
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
52302d4d 1600 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
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
52302d4d
LG
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
30fdf114
LG
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
52302d4d 1659 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
1660 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1661 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 1662 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
4afd3d04 1663 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
4234283c 1664 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
ea0f6464 1665 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
30fdf114
LG
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
52302d4d 1677 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 1678 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 1679 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
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
52302d4d 1687 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
ea0f6464 1688 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF",\r
30fdf114
LG
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
52302d4d 1704BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
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
52302d4d 1760UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r