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