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