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