]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools/VfrCompile: Avoid possible NULL pointer dereference
[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 "assert.h"
18 #include "VfrFormPkg.h"
19
20 /*
21 * The definition of CFormPkg's member function
22 */
23
24 SPendingAssign::SPendingAssign (
25 IN CHAR8 *Key,
26 IN VOID *Addr,
27 IN UINT32 Len,
28 IN UINT32 LineNo,
29 IN CONST CHAR8 *Msg
30 )
31 {
32 mKey = NULL;
33 mAddr = Addr;
34 mLen = Len;
35 mFlag = PENDING;
36 mLineNo = LineNo;
37 mMsg = NULL;
38 mNext = NULL;
39 if (Key != NULL) {
40 mKey = new CHAR8[strlen (Key) + 1];
41 if (mKey != NULL) {
42 strcpy (mKey, Key);
43 }
44 }
45
46 if (Msg != NULL) {
47 mMsg = new CHAR8[strlen (Msg) + 1];
48 if (mMsg != NULL) {
49 strcpy (mMsg, Msg);
50 }
51 }
52 }
53
54 SPendingAssign::~SPendingAssign (
55 VOID
56 )
57 {
58 if (mKey != NULL) {
59 delete mKey;
60 }
61 mAddr = NULL;
62 mLen = 0;
63 mLineNo = 0;
64 if (mMsg != NULL) {
65 delete mMsg;
66 }
67 mNext = NULL;
68 }
69
70 VOID
71 SPendingAssign::SetAddrAndLen (
72 IN VOID *Addr,
73 IN UINT32 LineNo
74 )
75 {
76 mAddr = Addr;
77 mLineNo = LineNo;
78 }
79
80 VOID
81 SPendingAssign::AssignValue (
82 IN VOID *Addr,
83 IN UINT32 Len
84 )
85 {
86 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));
87 mFlag = ASSIGNED;
88 }
89
90 CHAR8 *
91 SPendingAssign::GetKey (
92 VOID
93 )
94 {
95 return mKey;
96 }
97
98 CFormPkg::CFormPkg (
99 IN UINT32 BufferSize
100 )
101 {
102 CHAR8 *BufferStart;
103 CHAR8 *BufferEnd;
104 SBufferNode *Node;
105
106 mPkgLength = 0;
107 mBufferNodeQueueHead = NULL;
108 mCurrBufferNode = NULL;
109
110 Node = new SBufferNode;
111 if (Node == NULL) {
112 return ;
113 }
114 BufferStart = new CHAR8[BufferSize];
115 if (BufferStart == NULL) {
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;
829 EFI_VFR_RETURN_CODE ReturnCode;
830 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
831 EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
832
833 //
834 // Declare all questions as Numeric in DisableIf True
835 //
836 // DisableIf
837 CIfrDisableIf DIObj;
838 DIObj.SetLineNo (LineNo);
839 *InsertOpcodeAddr = DIObj.GetObjBinAddr ();
840
841 //TrueOpcode
842 CIfrTrue TObj (LineNo);
843
844 // Declare Numeric qeustion for each undefined question.
845 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
846 if (pNode->mFlag == PENDING) {
847 CIfrNumeric CNObj;
848 EFI_VARSTORE_INFO Info;
849 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
850
851 CNObj.SetLineNo (LineNo);
852 CNObj.SetPrompt (0x0);
853 CNObj.SetHelp (0x0);
854
855 //
856 // Register this question, assume it is normal question, not date or time question
857 //
858 VarStr = pNode->mKey;
859 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
860 if (ReturnCode != VFR_RETURN_SUCCESS) {
861 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
862 return ReturnCode;
863 }
864
865 #ifdef VFREXP_DEBUG
866 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
867 #endif
868 //
869 // Get Question Info, framework vfr VarName == StructName
870 //
871 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);
872 if (ReturnCode != VFR_RETURN_SUCCESS) {
873 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
874 return ReturnCode;
875 }
876 //
877 // Get VarStoreType
878 //
879 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
880 if (ReturnCode != VFR_RETURN_SUCCESS) {
881 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
882 return ReturnCode;
883 }
884 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);
885
886 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
887 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
888 } else {
889 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
890 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
891 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
892 VarStr = pNode->mKey;
893 //convert VarStr with store name to VarStr with structure name
894 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
895 if (ReturnCode == VFR_RETURN_SUCCESS) {
896 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
897 NewStr[0] = '\0';
898 strcpy (NewStr, SName);
899 strcat (NewStr, VarStr + strlen (FName));
900 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);
901 delete NewStr;
902 }
903 } else {
904 ReturnCode = VFR_RETURN_UNSUPPORTED;
905 }
906 }
907 if (ReturnCode != VFR_RETURN_SUCCESS) {
908 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
909 return ReturnCode;
910 }
911
912 CNObj.SetQuestionId (QId);
913 CNObj.SetVarStoreInfo (&Info);
914 //
915 // Numeric doesn't support BOOLEAN data type.
916 // BOOLEAN type has the same data size to UINT8.
917 //
918 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
919 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
920 }
921 CNObj.SetFlags (0, Info.mVarType);
922 //
923 // Use maximum value not to limit the vaild value for the undefined question.
924 //
925 switch (Info.mVarType) {
926 case EFI_IFR_TYPE_NUM_SIZE_64:
927 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);
928 ShrinkSize = 0;
929 break;
930 case EFI_IFR_TYPE_NUM_SIZE_32:
931 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);
932 ShrinkSize = 12;
933 break;
934 case EFI_IFR_TYPE_NUM_SIZE_16:
935 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);
936 ShrinkSize = 18;
937 break;
938 case EFI_IFR_TYPE_NUM_SIZE_8:
939 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);
940 ShrinkSize = 21;
941 break;
942 default:
943 break;
944 }
945 CNObj.ShrinkBinSize (ShrinkSize);
946
947 //
948 // For undefined Efi VarStore type question
949 // Append the extended guided opcode to contain VarName
950 //
951 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {
952 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
953 CVNObj.SetLineNo (LineNo);
954 }
955
956 //
957 // End for Numeric
958 //
959 CIfrEnd CEObj;
960 CEObj.SetLineNo (LineNo);
961 }
962 }
963
964 //
965 // End for DisableIf
966 //
967 CIfrEnd SEObj;
968 SEObj.SetLineNo (LineNo);
969
970 return VFR_RETURN_SUCCESS;
971 }
972
973 CFormPkg gCFormPkg;
974
975 SIfrRecord::SIfrRecord (
976 VOID
977 )
978 {
979 mIfrBinBuf = NULL;
980 mBinBufLen = 0;
981 mLineNo = 0xFFFFFFFF;
982 mOffset = 0xFFFFFFFF;
983 mNext = NULL;
984 }
985
986 SIfrRecord::~SIfrRecord (
987 VOID
988 )
989 {
990 if (mIfrBinBuf != NULL) {
991 //delete mIfrBinBuf;
992 mIfrBinBuf = NULL;
993 }
994 mLineNo = 0xFFFFFFFF;
995 mOffset = 0xFFFFFFFF;
996 mBinBufLen = 0;
997 mNext = NULL;
998 }
999
1000 CIfrRecordInfoDB::CIfrRecordInfoDB (
1001 VOID
1002 )
1003 {
1004 mSwitch = TRUE;
1005 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
1006 mIfrRecordListHead = NULL;
1007 mIfrRecordListTail = NULL;
1008 mAllDefaultTypeCount = 0;
1009 for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {
1010 mAllDefaultIdArray[i] = 0xffff;
1011 }
1012 }
1013
1014 CIfrRecordInfoDB::~CIfrRecordInfoDB (
1015 VOID
1016 )
1017 {
1018 SIfrRecord *pNode;
1019
1020 while (mIfrRecordListHead != NULL) {
1021 pNode = mIfrRecordListHead;
1022 mIfrRecordListHead = mIfrRecordListHead->mNext;
1023 delete pNode;
1024 }
1025 }
1026
1027 SIfrRecord *
1028 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1029 IN UINT32 RecordIdx
1030 )
1031 {
1032 UINT32 Idx;
1033 SIfrRecord *pNode = NULL;
1034
1035 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
1036 return NULL;
1037 }
1038
1039 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
1040 (Idx != RecordIdx) && (pNode != NULL);
1041 Idx++, pNode = pNode->mNext)
1042 ;
1043
1044 return pNode;
1045 }
1046
1047 UINT32
1048 CIfrRecordInfoDB::IfrRecordRegister (
1049 IN UINT32 LineNo,
1050 IN CHAR8 *IfrBinBuf,
1051 IN UINT8 BinBufLen,
1052 IN UINT32 Offset
1053 )
1054 {
1055 SIfrRecord *pNew;
1056
1057 if (mSwitch == FALSE) {
1058 return EFI_IFR_RECORDINFO_IDX_INVALUD;
1059 }
1060
1061 if ((pNew = new SIfrRecord) == NULL) {
1062 return EFI_IFR_RECORDINFO_IDX_INVALUD;
1063 }
1064
1065 if (mIfrRecordListHead == NULL) {
1066 mIfrRecordListHead = pNew;
1067 mIfrRecordListTail = pNew;
1068 } else {
1069 mIfrRecordListTail->mNext = pNew;
1070 mIfrRecordListTail = pNew;
1071 }
1072 mRecordCount++;
1073
1074 return mRecordCount;
1075 }
1076
1077 VOID
1078 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1079 IN UINT32 RecordIdx,
1080 IN UINT32 LineNo,
1081 IN CHAR8 *BinBuf,
1082 IN UINT8 BinBufLen,
1083 IN UINT32 Offset
1084 )
1085 {
1086 SIfrRecord *pNode;
1087 SIfrRecord *Prev;
1088
1089 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
1090 return;
1091 }
1092
1093 if (LineNo == 0) {
1094 //
1095 // Line number is not specified explicitly, try to use line number of previous opcode
1096 //
1097 Prev = GetRecordInfoFromIdx (RecordIdx - 1);
1098 if (Prev != NULL) {
1099 LineNo = Prev->mLineNo;
1100 }
1101 }
1102
1103 pNode->mLineNo = LineNo;
1104 pNode->mOffset = Offset;
1105 pNode->mBinBufLen = BinBufLen;
1106 pNode->mIfrBinBuf = BinBuf;
1107
1108 }
1109
1110 VOID
1111 CIfrRecordInfoDB::IfrRecordOutput (
1112 OUT PACKAGE_DATA &TBuffer
1113 )
1114 {
1115 CHAR8 *Temp;
1116 SIfrRecord *pNode;
1117
1118 if (TBuffer.Buffer != NULL) {
1119 delete TBuffer.Buffer;
1120 }
1121
1122 TBuffer.Size = 0;
1123 TBuffer.Buffer = NULL;
1124
1125
1126 if (mSwitch == FALSE) {
1127 return;
1128 }
1129
1130 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1131 TBuffer.Size += pNode->mBinBufLen;
1132 }
1133
1134 if (TBuffer.Size != 0) {
1135 TBuffer.Buffer = new CHAR8[TBuffer.Size];
1136 } else {
1137 return;
1138 }
1139
1140 Temp = TBuffer.Buffer;
1141
1142 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1143 if (pNode->mIfrBinBuf != NULL) {
1144 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
1145 Temp += pNode->mBinBufLen;
1146 }
1147 }
1148
1149 return;
1150 }
1151
1152 VOID
1153 CIfrRecordInfoDB::IfrRecordOutput (
1154 IN FILE *File,
1155 IN UINT32 LineNo
1156 )
1157 {
1158 SIfrRecord *pNode;
1159 UINT8 Index;
1160 UINT32 TotalSize;
1161
1162 if (mSwitch == FALSE) {
1163 return;
1164 }
1165
1166 if (File == NULL) {
1167 return;
1168 }
1169
1170 TotalSize = 0;
1171
1172 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1173 if (pNode->mLineNo == LineNo || LineNo == 0) {
1174 fprintf (File, ">%08X: ", pNode->mOffset);
1175 TotalSize += pNode->mBinBufLen;
1176 if (pNode->mIfrBinBuf != NULL) {
1177 for (Index = 0; Index < pNode->mBinBufLen; Index++) {
1178 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
1179 }
1180 }
1181 fprintf (File, "\n");
1182 }
1183 }
1184
1185 if (LineNo == 0) {
1186 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
1187 }
1188 }
1189
1190 //
1191 // for framework vfr file
1192 // adjust opcode sequence for uefi IFR format
1193 // adjust inconsistent and varstore into the right position.
1194 //
1195 BOOLEAN
1196 CIfrRecordInfoDB::CheckQuestionOpCode (
1197 IN UINT8 OpCode
1198 )
1199 {
1200 switch (OpCode) {
1201 case EFI_IFR_CHECKBOX_OP:
1202 case EFI_IFR_NUMERIC_OP:
1203 case EFI_IFR_PASSWORD_OP:
1204 case EFI_IFR_ONE_OF_OP:
1205 case EFI_IFR_ACTION_OP:
1206 case EFI_IFR_STRING_OP:
1207 case EFI_IFR_DATE_OP:
1208 case EFI_IFR_TIME_OP:
1209 case EFI_IFR_ORDERED_LIST_OP:
1210 case EFI_IFR_REF_OP:
1211 return TRUE;
1212 default:
1213 return FALSE;
1214 }
1215 }
1216
1217 BOOLEAN
1218 CIfrRecordInfoDB::CheckIdOpCode (
1219 IN UINT8 OpCode
1220 )
1221 {
1222 switch (OpCode) {
1223 case EFI_IFR_EQ_ID_VAL_OP:
1224 case EFI_IFR_EQ_ID_ID_OP:
1225 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1226 case EFI_IFR_QUESTION_REF1_OP:
1227 return TRUE;
1228 default:
1229 return FALSE;
1230 }
1231 }
1232
1233 EFI_QUESTION_ID
1234 CIfrRecordInfoDB::GetOpcodeQuestionId (
1235 IN EFI_IFR_OP_HEADER *OpHead
1236 )
1237 {
1238 EFI_IFR_QUESTION_HEADER *QuestionHead;
1239
1240 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
1241
1242 return QuestionHead->QuestionId;
1243 }
1244
1245 SIfrRecord *
1246 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1247 IN UINT32 Offset
1248 )
1249 {
1250 SIfrRecord *pNode = NULL;
1251
1252 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1253 if (pNode->mOffset == Offset) {
1254 return pNode;
1255 }
1256 }
1257
1258 return pNode;
1259 }
1260
1261 /**
1262 Add just the op code position.
1263
1264 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1265 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1266
1267 From
1268
1269 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1270
1271 To
1272
1273 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1274
1275 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1276 so new records are appennded to the end of OriginalIfrRecordListTail.
1277
1278 From
1279
1280 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1281
1282 To
1283
1284 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1285
1286
1287 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1288
1289 **/
1290 BOOLEAN
1291 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1292 IN BOOLEAN CreateOpcodeAfterParsingVfr
1293 )
1294 {
1295 UINT32 OpcodeOffset;
1296 SIfrRecord *pNode, *pPreNode;
1297 SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;
1298 SIfrRecord *pNodeBeforeDynamic;
1299
1300 pAdjustNode = NULL;
1301 pNodeBeforeDynamic = NULL;
1302 OpcodeOffset = 0;
1303
1304 //
1305 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1306 // and the node before pDynamicOpcodeNode.
1307 //
1308 for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {
1309 if (OpcodeOffset == gAdjustOpcodeOffset) {
1310 pAdjustNode = pNode;
1311 pNodeBeforeAdjust = pPreNode;
1312 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
1313 pNodeBeforeDynamic = pPreNode;
1314 }
1315 if (pNode->mNext != NULL) {
1316 pPreNode = pNode;
1317 }
1318 OpcodeOffset += pNode->mBinBufLen;
1319 }
1320
1321 //
1322 // Check the nodes whether exist.
1323 //
1324 if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {
1325 return FALSE;
1326 }
1327
1328 //
1329 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1330 //
1331 pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;
1332 if (CreateOpcodeAfterParsingVfr) {
1333 //
1334 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1335 //
1336 mIfrRecordListTail->mNext = pAdjustNode;
1337 mIfrRecordListTail = pNodeBeforeDynamic;
1338 mIfrRecordListTail->mNext = NULL;
1339 } else {
1340 //
1341 //pPreNode is the end of pDynamicNode(Case1).
1342 //
1343 pPreNode->mNext = pAdjustNode;
1344 pNodeBeforeDynamic->mNext = mIfrRecordListTail;
1345 }
1346
1347 return TRUE;
1348 }
1349
1350 /**
1351 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1352
1353 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1354
1355 **/
1356 VOID
1357 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1358 IN BOOLEAN CreateOpcodeAfterParsingVfr
1359 )
1360 {
1361 SIfrRecord *pRecord;
1362
1363 //
1364 // Base on the original offset info to update the record list.
1365 //
1366 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {
1367 gCVfrErrorHandle.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");
1368 }
1369
1370 //
1371 // Base on the opcode binary length to recalculate the offset for each opcode.
1372 //
1373 IfrAdjustOffsetForRecord();
1374
1375 //
1376 // Base on the offset to find the binary address.
1377 //
1378 pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);
1379 while (pRecord != NULL) {
1380 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);
1381 pRecord = pRecord->mNext;
1382 }
1383 }
1384
1385
1386 VOID
1387 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1388 VOID
1389 )
1390 {
1391 UINT32 OpcodeOffset;
1392 SIfrRecord *pNode;
1393
1394 OpcodeOffset = 0;
1395 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1396 pNode->mOffset = OpcodeOffset;
1397 OpcodeOffset += pNode->mBinBufLen;
1398 }
1399 }
1400
1401 EFI_VFR_RETURN_CODE
1402 CIfrRecordInfoDB::IfrRecordAdjust (
1403 VOID
1404 )
1405 {
1406 SIfrRecord *pNode, *preNode;
1407 SIfrRecord *uNode, *tNode;
1408 EFI_IFR_OP_HEADER *OpHead, *tOpHead;
1409 EFI_QUESTION_ID QuestionId;
1410 UINT32 StackCount;
1411 UINT32 QuestionScope;
1412 UINT32 OpcodeOffset;
1413 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
1414 EFI_VFR_RETURN_CODE Status;
1415
1416 //
1417 // Init local variable
1418 //
1419 Status = VFR_RETURN_SUCCESS;
1420 pNode = mIfrRecordListHead;
1421 preNode = pNode;
1422 QuestionScope = 0;
1423 while (pNode != NULL) {
1424 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
1425
1426 //
1427 // make sure the inconsistent opcode in question scope
1428 //
1429 if (QuestionScope > 0) {
1430 QuestionScope += OpHead->Scope;
1431 if (OpHead->OpCode == EFI_IFR_END_OP) {
1432 QuestionScope --;
1433 }
1434 }
1435
1436 if (CheckQuestionOpCode (OpHead->OpCode)) {
1437 QuestionScope = 1;
1438 }
1439 //
1440 // for the inconsistent opcode not in question scope, adjust it
1441 //
1442 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
1443 //
1444 // for inconsistent opcode not in question scope
1445 //
1446
1447 //
1448 // Count inconsistent opcode Scope
1449 //
1450 StackCount = OpHead->Scope;
1451 QuestionId = EFI_QUESTION_ID_INVALID;
1452 tNode = pNode;
1453 while (tNode != NULL && StackCount > 0) {
1454 tNode = tNode->mNext;
1455 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
1456 //
1457 // Calculate Scope Number
1458 //
1459 StackCount += tOpHead->Scope;
1460 if (tOpHead->OpCode == EFI_IFR_END_OP) {
1461 StackCount --;
1462 }
1463 //
1464 // by IdEqual opcode to get QuestionId
1465 //
1466 if (QuestionId == EFI_QUESTION_ID_INVALID &&
1467 CheckIdOpCode (tOpHead->OpCode)) {
1468 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
1469 }
1470 }
1471 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
1472 //
1473 // report error; not found
1474 //
1475 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
1476 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1477 Status = VFR_RETURN_MISMATCHED;
1478 break;
1479 }
1480 //
1481 // extract inconsistent opcode list
1482 // pNode is Incosistent opcode, tNode is End Opcode
1483 //
1484
1485 //
1486 // insert inconsistent opcode list into the right question scope by questionid
1487 //
1488 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
1489 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
1490 if (CheckQuestionOpCode (tOpHead->OpCode) &&
1491 (QuestionId == GetOpcodeQuestionId (tOpHead))) {
1492 break;
1493 }
1494 }
1495 //
1496 // insert inconsistent opcode list and check LATE_CHECK flag
1497 //
1498 if (uNode != NULL) {
1499 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
1500 //
1501 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1502 //
1503 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
1504 }
1505
1506 //
1507 // skip the default storage for Date and Time
1508 //
1509 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
1510 uNode = uNode->mNext;
1511 }
1512
1513 preNode->mNext = tNode->mNext;
1514 tNode->mNext = uNode->mNext;
1515 uNode->mNext = pNode;
1516 //
1517 // reset pNode to head list, scan the whole list again.
1518 //
1519 pNode = mIfrRecordListHead;
1520 preNode = pNode;
1521 QuestionScope = 0;
1522 continue;
1523 } else {
1524 //
1525 // not found matched question id, report error
1526 //
1527 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
1528 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1529 Status = VFR_RETURN_MISMATCHED;
1530 break;
1531 }
1532 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
1533 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
1534 //
1535 // for new added group of varstore opcode
1536 //
1537 tNode = pNode;
1538 while (tNode->mNext != NULL) {
1539 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
1540 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
1541 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
1542 break;
1543 }
1544 tNode = tNode->mNext;
1545 }
1546
1547 if (tNode->mNext == NULL) {
1548 //
1549 // invalid IfrCode, IfrCode end by EndOpCode
1550 //
1551 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
1552 Status = VFR_RETURN_MISMATCHED;
1553 break;
1554 }
1555
1556 if (tOpHead->OpCode != EFI_IFR_END_OP) {
1557 //
1558 // not new added varstore, which are not needed to be adjust.
1559 //
1560 preNode = tNode;
1561 pNode = tNode->mNext;
1562 continue;
1563 } else {
1564 //
1565 // move new added varstore opcode to the position befor form opcode
1566 // varstore opcode between pNode and tNode
1567 //
1568
1569 //
1570 // search form opcode from begin
1571 //
1572 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
1573 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
1574 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
1575 break;
1576 }
1577 }
1578 //
1579 // Insert varstore opcode beform form opcode if form opcode is found
1580 //
1581 if (uNode->mNext != NULL) {
1582 preNode->mNext = tNode->mNext;
1583 tNode->mNext = uNode->mNext;
1584 uNode->mNext = pNode;
1585 //
1586 // reset pNode to head list, scan the whole list again.
1587 //
1588 pNode = mIfrRecordListHead;
1589 preNode = pNode;
1590 QuestionScope = 0;
1591 continue;
1592 } else {
1593 //
1594 // not found form, continue scan IfrRecord list
1595 //
1596 preNode = tNode;
1597 pNode = tNode->mNext;
1598 continue;
1599 }
1600 }
1601 }
1602 //
1603 // next node
1604 //
1605 preNode = pNode;
1606 pNode = pNode->mNext;
1607 }
1608
1609 //
1610 // Update Ifr Opcode Offset
1611 //
1612 if (Status == VFR_RETURN_SUCCESS) {
1613 IfrAdjustOffsetForRecord ();
1614 }
1615 return Status;
1616 }
1617
1618 /**
1619 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1620 given by expression, should save the default info for the Buffer VarStore.
1621
1622 @param DefaultId The default id.
1623 @param pQuestionNode Point to the question opcode node.
1624 @param Value The default value.
1625 **/
1626 VOID
1627 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1628 IN UINT16 DefaultId,
1629 IN SIfrRecord *pQuestionNode,
1630 IN EFI_IFR_TYPE_VALUE Value
1631 )
1632 {
1633 CHAR8 *VarStoreName = NULL;
1634 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
1635 EFI_GUID *VarGuid = NULL;
1636 EFI_VARSTORE_INFO VarInfo;
1637 EFI_IFR_QUESTION_HEADER *QuestionHead;
1638 EFI_IFR_OP_HEADER *pQuestionOpHead;
1639
1640 pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
1641 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);
1642
1643 //
1644 // Get the Var Store name and type.
1645 //
1646 gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);
1647 VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);
1648 VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);
1649
1650 //
1651 // Only for Buffer storage need to save the default info in the storage.
1652 // Other type storage, just return.
1653 //
1654 if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {
1655 return;
1656 } else {
1657 VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;
1658 VarInfo.mVarStoreId = QuestionHead->VarStoreId;
1659 }
1660
1661 //
1662 // Get the buffer storage info about this question.
1663 //
1664 gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);
1665
1666 //
1667 // Add action.
1668 //
1669 gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
1670 DefaultId,
1671 VarInfo,
1672 VarStoreName,
1673 VarGuid,
1674 VarInfo.mVarType,
1675 Value
1676 );
1677 }
1678
1679 /**
1680 Record the number and default id of all defaultstore opcode.
1681
1682 **/
1683 VOID
1684 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1685 VOID
1686 )
1687 {
1688 SIfrRecord *pNode;
1689 EFI_IFR_OP_HEADER *pOpHead;
1690 EFI_IFR_DEFAULTSTORE *DefaultStore;
1691
1692 pNode = mIfrRecordListHead;
1693 mAllDefaultTypeCount = 0;
1694
1695 while (pNode != NULL) {
1696 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
1697
1698 if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){
1699 DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;
1700 mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;
1701 }
1702 pNode = pNode->mNext;
1703 }
1704 }
1705
1706 /**
1707 Create new default opcode record.
1708
1709 @param Size The new default opcode size.
1710 @param DefaultId The new default id.
1711 @param Type The new default type.
1712 @param LineNo The line number of the new record.
1713 @param Value The new default value.
1714
1715 **/
1716 VOID
1717 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1718 IN UINT8 Size,
1719 IN UINT16 DefaultId,
1720 IN UINT8 Type,
1721 IN UINT32 LineNo,
1722 IN EFI_IFR_TYPE_VALUE Value
1723 )
1724 {
1725 CIfrDefault *DObj;
1726 CIfrDefault2 *DObj2;
1727
1728 DObj = NULL;
1729 DObj2 = NULL;
1730
1731 if (Type == EFI_IFR_TYPE_OTHER) {
1732 DObj2 = new CIfrDefault2 (Size);
1733 DObj2->SetDefaultId(DefaultId);
1734 DObj2->SetType(Type);
1735 DObj2->SetLineNo(LineNo);
1736 DObj2->SetScope (1);
1737 delete DObj2;
1738 } else {
1739 DObj = new CIfrDefault (Size);
1740 DObj->SetDefaultId(DefaultId);
1741 DObj->SetType(Type);
1742 DObj->SetLineNo(LineNo);
1743 DObj->SetValue (Value);
1744 delete DObj;
1745 }
1746 }
1747
1748 /**
1749 Create new default opcode for question base on the QuestionDefaultInfo.
1750
1751 @param pQuestionNode Point to the question opcode Node.
1752 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1753
1754 **/
1755 VOID
1756 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1757 IN SIfrRecord *pQuestionNode,
1758 IN QuestionDefaultRecord *QuestionDefaultInfo
1759 )
1760 {
1761 EFI_IFR_OP_HEADER *pOpHead;
1762 EFI_IFR_DEFAULT *Default;
1763 SIfrRecord *pSNode;
1764 SIfrRecord *pENode;
1765 SIfrRecord *pDefaultNode;
1766 CIfrObj *Obj;
1767 CHAR8 *ObjBinBuf;
1768 UINT8 ScopeCount;
1769 UINT8 OpcodeNumber;
1770 UINT8 OpcodeCount;
1771 UINT8 DefaultSize;
1772 EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;
1773 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;
1774
1775 CheckBoxDefaultValue.b = 1;
1776 pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
1777 ScopeCount = 0;
1778 OpcodeCount = 0;
1779 Obj = NULL;
1780
1781 //
1782 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1783 //
1784 gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;
1785 //
1786 // Case 1:
1787 // For oneof, the default with smallest default id is given by the option flag.
1788 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1789 //
1790 if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
1791 DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;
1792 DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
1793 DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);
1794 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1795 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1796 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);
1797 //
1798 // Save the new created default in the buffer storage.
1799 //
1800 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);
1801 }
1802 }
1803 return;
1804 }
1805
1806 //
1807 // Case2:
1808 // For checkbox, the default with smallest default id is given by the question flag.
1809 // And create the missing defaults with true value.
1810 //
1811 if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
1812 DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);
1813 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1814 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1815 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);
1816 //
1817 // Save the new created default.
1818 //
1819 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);
1820 }
1821 }
1822 return;
1823 }
1824
1825 //
1826 // Case3:
1827 // The default with smallest default id is given by the default opcode.
1828 // So create the missing defaults base on the value in the default opcode.
1829 //
1830
1831 //
1832 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1833 //
1834 pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;
1835 Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;
1836 //
1837 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1838 //
1839 gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;
1840
1841 if (Default->Type == EFI_IFR_TYPE_OTHER) {
1842 //
1843 // EFI_IFR_DEFAULT_2 opcode.
1844 //
1845 // Point to the first expression opcode.
1846 //
1847 pSNode = pDefaultNode->mNext;
1848 ScopeCount++;
1849 //
1850 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1851 //
1852 while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {
1853 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1854 if (pOpHead->Scope == 1) {
1855 ScopeCount++;
1856 }
1857 if (pOpHead->OpCode == EFI_IFR_END_OP) {
1858 ScopeCount--;
1859 }
1860 pENode = pSNode;
1861 pSNode = pSNode->mNext;
1862 OpcodeCount++;
1863 }
1864
1865 assert (pSNode);
1866 assert (pENode);
1867
1868 //
1869 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1870 //
1871 gAdjustOpcodeOffset = pSNode->mOffset;
1872 //
1873 // Create new default opcode node for missing default.
1874 //
1875 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1876 OpcodeNumber = OpcodeCount;
1877 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1878 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);
1879 //
1880 // Point to the first expression opcode node.
1881 //
1882 pSNode = pDefaultNode->mNext;
1883 //
1884 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1885 //
1886 while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {
1887 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1888 Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);
1889 assert (Obj != NULL);
1890 Obj->SetLineNo (pSNode->mLineNo);
1891 ObjBinBuf = Obj->GetObjBinAddr();
1892 memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);
1893 delete Obj;
1894 pSNode = pSNode->mNext;
1895 }
1896 }
1897 }
1898 } else {
1899 //
1900 // EFI_IFR_DEFAULT opcode.
1901 //
1902 // Create new default opcode node for missing default.
1903 //
1904 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1905 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1906 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);
1907 //
1908 // Save the new created default in the buffer storage..
1909 //
1910 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);
1911 }
1912 }
1913 }
1914 }
1915
1916 /**
1917 Parse the default information in a question, get the QuestionDefaultInfo.
1918
1919 @param pQuestionNode Point to the question record Node.
1920 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1921 **/
1922 VOID
1923 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1924 IN SIfrRecord *pQuestionNode,
1925 OUT QuestionDefaultRecord *QuestionDefaultInfo
1926 )
1927 {
1928 SIfrRecord *pSNode;
1929 EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;
1930 EFI_IFR_OP_HEADER *pSOpHead;
1931 EFI_IFR_CHECKBOX *CheckBoxOpcode;
1932 EFI_IFR_DEFAULT *DefaultOpcode;
1933 BOOLEAN IsOneOfOpcode;
1934 UINT16 SmallestDefaultId;
1935 UINT8 ScopeCount;
1936
1937 SmallestDefaultId = 0xffff;
1938 IsOneOfOpcode = FALSE;
1939 ScopeCount = 0;
1940 pSNode = pQuestionNode;
1941
1942 //
1943 // Parse all the opcodes in the Question.
1944 //
1945 while (pSNode != NULL) {
1946 pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1947 //
1948 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1949 // Scopes may be nested within other scopes.
1950 // When finishing parsing a question, the scope count must be zero.
1951 //
1952 if (pSOpHead->Scope == 1) {
1953 ScopeCount++;
1954 }
1955 if (pSOpHead->OpCode == EFI_IFR_END_OP) {
1956 ScopeCount--;
1957 }
1958 //
1959 // Check whether finishing parsing a question.
1960 //
1961 if (ScopeCount == 0) {
1962 break;
1963 }
1964
1965 //
1966 // Record the default information in the question.
1967 //
1968 switch (pSOpHead->OpCode) {
1969 case EFI_IFR_ONE_OF_OP:
1970 IsOneOfOpcode = TRUE;
1971 break;
1972 case EFI_IFR_CHECKBOX_OP:
1973 //
1974 // The default info of check box may be given by flag.
1975 // So need to check the flag of check box.
1976 //
1977 CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;
1978 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {
1979 //
1980 // Check whether need to update the smallest default id.
1981 //
1982 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
1983 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
1984 }
1985 //
1986 // Update the QuestionDefaultInfo.
1987 //
1988 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1989 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
1990 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1991 QuestionDefaultInfo->mDefaultNumber ++;
1992 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
1993 }
1994 break;
1995 }
1996 }
1997 }
1998 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {
1999 //
2000 // Check whether need to update the smallest default id.
2001 //
2002 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2003 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2004 }
2005 //
2006 // Update the QuestionDefaultInfo.
2007 //
2008 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
2009 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2010 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2011 QuestionDefaultInfo->mDefaultNumber ++;
2012 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2013 }
2014 break;
2015 }
2016 }
2017 }
2018 break;
2019 case EFI_IFR_ONE_OF_OPTION_OP:
2020 if (!IsOneOfOpcode) {
2021 //
2022 // Only check the option in oneof.
2023 //
2024 break;
2025 }
2026 OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;
2027 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
2028 //
2029 // The option is used as the standard default.
2030 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2031 //
2032 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
2033 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2034 QuestionDefaultInfo->mDefaultValueRecord = pSNode;
2035 }
2036 //
2037 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2038 //
2039 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
2040 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
2041 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2042 QuestionDefaultInfo->mDefaultNumber ++;
2043 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2044 }
2045 break;
2046 }
2047 }
2048 }
2049 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {
2050 //
2051 // This option is used as the manufacture default.
2052 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2053 //
2054 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2055 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2056 QuestionDefaultInfo->mDefaultValueRecord = pSNode;
2057 }
2058 //
2059 // Update the QuestionDefaultInfo.
2060 //
2061 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
2062 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2063 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2064 QuestionDefaultInfo->mDefaultNumber ++;
2065 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2066 }
2067 break;
2068 }
2069 }
2070 }
2071 break;
2072 case EFI_IFR_DEFAULT_OP:
2073 DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;
2074 //
2075 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2076 //
2077 if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {
2078 SmallestDefaultId = DefaultOpcode->DefaultId;
2079 QuestionDefaultInfo->mDefaultValueRecord= pSNode;
2080 QuestionDefaultInfo->mIsDefaultOpcode= TRUE;
2081 }
2082 //
2083 // Update the QuestionDefaultInfo.
2084 //
2085 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){
2086 if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {
2087 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2088 QuestionDefaultInfo->mDefaultNumber ++;
2089 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2090 }
2091 break;
2092 }
2093 }
2094 break;
2095 default:
2096 break;
2097 }
2098 //
2099 // Parse next opcode in this question.
2100 //
2101 pSNode = pSNode->mNext;
2102 }
2103 }
2104
2105 /**
2106 Check or add default for question if need.
2107
2108 This function will check the default info for question.
2109 If the question has default, but the default number < defaultstore opcode number.
2110 will do following two action :
2111
2112 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2113 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2114
2115 We assume that the two options can not be TRUE at same time.
2116 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2117
2118 @param AutoDefault Add default for question if needed
2119 @param CheckDefault Check the default info, if missing default, generates an error.
2120
2121 **/
2122 VOID
2123 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2124 BOOLEAN AutoDefault,
2125 BOOLEAN CheckDefault
2126 )
2127 {
2128 SIfrRecord *pNode;
2129 SIfrRecord *pTailNode;
2130 SIfrRecord *pStartAdjustNode;
2131 EFI_IFR_OP_HEADER *pOpHead;
2132 QuestionDefaultRecord QuestionDefaultInfo;
2133 UINT8 MissingDefaultCount;
2134 CHAR8 Msg[MAX_STRING_LEN] = {0, };
2135
2136 pNode = mIfrRecordListHead;
2137
2138 //
2139 // Record the number and default id of all defaultstore opcode.
2140 //
2141 IfrGetDefaultStoreInfo ();
2142
2143 while (pNode != NULL) {
2144 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
2145 //
2146 // Check whether is question opcode.
2147 //
2148 if (CheckQuestionOpCode (pOpHead->OpCode)) {
2149 //
2150 // Initialize some local variables here, because they vary with question.
2151 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2152 //
2153 memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));
2154 pTailNode = mIfrRecordListTail;
2155 //
2156 // Get the QuestionDefaultInfo for current question.
2157 //
2158 IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);
2159
2160 if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {
2161 if (AutoDefault) {
2162 //
2163 // Create default for question which misses default.
2164 //
2165 IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);
2166
2167 //
2168 // Adjust the buffer content.
2169 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2170 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2171 //
2172 pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);
2173 gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);
2174
2175 //
2176 // Update the record info.
2177 //
2178 IfrUpdateRecordInfoForDynamicOpcode (TRUE);
2179 } else if (CheckDefault) {
2180 //
2181 // Generate an error for question which misses default.
2182 //
2183 MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;
2184 sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);
2185 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);
2186 }
2187 }
2188 }
2189 //
2190 // parse next opcode.
2191 //
2192 pNode = pNode->mNext;
2193 }
2194 }
2195
2196 CIfrRecordInfoDB gCIfrRecordInfoDB;
2197
2198 VOID
2199 CIfrObj::_EMIT_PENDING_OBJ (
2200 VOID
2201 )
2202 {
2203 CHAR8 *ObjBinBuf = NULL;
2204
2205 //
2206 // do nothing
2207 //
2208 if (!mDelayEmit || !gCreateOp) {
2209 return;
2210 }
2211
2212 mPkgOffset = gCFormPkg.GetPkgLength ();
2213 //
2214 // update data buffer to package data
2215 //
2216 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
2217 if (ObjBinBuf != NULL) {
2218 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
2219 }
2220
2221 //
2222 // update bin buffer to package data buffer
2223 //
2224 if (mObjBinBuf != NULL) {
2225 delete mObjBinBuf;
2226 mObjBinBuf = ObjBinBuf;
2227 }
2228
2229 mDelayEmit = FALSE;
2230 }
2231
2232 /*
2233 * The definition of CIfrObj's member function
2234 */
2235 static struct {
2236 UINT8 mSize;
2237 UINT8 mScope;
2238 } gOpcodeSizesScopeTable[] = {
2239 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2240 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
2241 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
2242 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
2243 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
2244 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2245 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
2246 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
2247 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
2248 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2249 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2250 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
2251 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
2252 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
2253 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2254 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
2255 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2256 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2257 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2258 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
2259 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2260 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
2261 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
2262 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
2263 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
2264 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2265 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
2266 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
2267 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
2268 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
2269 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2270 { 0, 0 }, // 0x1F
2271 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2272 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2273 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
2274 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2275 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
2276 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2277 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2278 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2279 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
2280 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
2281 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2282 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
2283 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
2284 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
2285 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
2286 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2287 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
2288 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
2289 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2290 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
2291 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2292 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
2293 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
2294 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
2295 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2296 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2297 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
2298 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
2299 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
2300 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
2301 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2302 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
2303 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
2304 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2305 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
2306 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
2307 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
2308 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
2309 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
2310 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
2311 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
2312 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
2313 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2314 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
2315 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
2316 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
2317 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2318 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
2319 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
2320 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
2321 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
2322 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
2323 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
2324 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
2325 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
2326 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
2327 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
2328 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
2329 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
2330 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
2331 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2332 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2333 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
2334 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
2335 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2336 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2337 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2338 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2339 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2340 };
2341
2342 #ifdef CIFROBJ_DEUBG
2343 static struct {
2344 CHAR8 *mIfrName;
2345 } gIfrObjPrintDebugTable[] = {
2346 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2347 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2348 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2349 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2350 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2351 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2352 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2353 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2354 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2355 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2356 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2357 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2358 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2359 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2360 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2361 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2362 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2363 };
2364
2365 VOID
2366 CIFROBJ_DEBUG_PRINT (
2367 IN UINT8 OpCode
2368 )
2369 {
2370 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
2371 }
2372 #else
2373
2374 #define CIFROBJ_DEBUG_PRINT(OpCode)
2375
2376 #endif
2377
2378 BOOLEAN gCreateOp = TRUE;
2379
2380 CIfrObj::CIfrObj (
2381 IN UINT8 OpCode,
2382 OUT CHAR8 **IfrObj,
2383 IN UINT8 ObjBinLen,
2384 IN BOOLEAN DelayEmit
2385 )
2386 {
2387 mDelayEmit = DelayEmit;
2388 mPkgOffset = gCFormPkg.GetPkgLength ();
2389 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
2390 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
2391 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
2392
2393 assert (mObjBinBuf != NULL);
2394
2395 if (IfrObj != NULL) {
2396 *IfrObj = mObjBinBuf;
2397 }
2398
2399 CIFROBJ_DEBUG_PRINT (OpCode);
2400 }
2401
2402 CIfrObj::~CIfrObj (
2403 VOID
2404 )
2405 {
2406 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
2407 _EMIT_PENDING_OBJ ();
2408 }
2409
2410 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
2411 }
2412
2413 /*
2414 * The definition of CIfrObj's member function
2415 */
2416 UINT8 gScopeCount = 0;
2417
2418 CIfrOpHeader::CIfrOpHeader (
2419 IN UINT8 OpCode,
2420 IN VOID *StartAddr,
2421 IN UINT8 Length
2422 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
2423 {
2424 mHeader->OpCode = OpCode;
2425 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
2426 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
2427 }
2428
2429 CIfrOpHeader::CIfrOpHeader (
2430 IN CIfrOpHeader &OpHdr
2431 )
2432 {
2433 mHeader = OpHdr.mHeader;
2434 }
2435
2436 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };