]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTool/VfrCompile: Remove reset button opcode in CheckQuestionOpCode
[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 return TRUE;
1205 default:
1206 return FALSE;
1207 }
1208 }
1209
1210 BOOLEAN
1211 CIfrRecordInfoDB::CheckIdOpCode (
1212 IN UINT8 OpCode
1213 )
1214 {
1215 switch (OpCode) {
1216 case EFI_IFR_EQ_ID_VAL_OP:
1217 case EFI_IFR_EQ_ID_ID_OP:
1218 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1219 case EFI_IFR_QUESTION_REF1_OP:
1220 return TRUE;
1221 default:
1222 return FALSE;
1223 }
1224 }
1225
1226 EFI_QUESTION_ID
1227 CIfrRecordInfoDB::GetOpcodeQuestionId (
1228 IN EFI_IFR_OP_HEADER *OpHead
1229 )
1230 {
1231 EFI_IFR_QUESTION_HEADER *QuestionHead;
1232
1233 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
1234
1235 return QuestionHead->QuestionId;
1236 }
1237
1238 SIfrRecord *
1239 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1240 IN UINT32 Offset
1241 )
1242 {
1243 SIfrRecord *pNode = NULL;
1244
1245 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1246 if (pNode->mOffset == Offset) {
1247 return pNode;
1248 }
1249 }
1250
1251 return pNode;
1252 }
1253
1254 /**
1255 Add just the op code position.
1256
1257 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1258 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1259
1260 From
1261
1262 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1263
1264 To
1265
1266 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1267
1268 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1269 so new records are appennded to the end of OriginalIfrRecordListTail.
1270
1271 From
1272
1273 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1274
1275 To
1276
1277 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1278
1279
1280 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1281
1282 **/
1283 BOOLEAN
1284 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1285 IN BOOLEAN CreateOpcodeAfterParsingVfr
1286 )
1287 {
1288 UINT32 OpcodeOffset;
1289 SIfrRecord *pNode, *pPreNode;
1290 SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;
1291 SIfrRecord *pNodeBeforeDynamic;
1292
1293 pAdjustNode = NULL;
1294 pNodeBeforeDynamic = NULL;
1295 OpcodeOffset = 0;
1296
1297 //
1298 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1299 // and the node before pDynamicOpcodeNode.
1300 //
1301 for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {
1302 if (OpcodeOffset == gAdjustOpcodeOffset) {
1303 pAdjustNode = pNode;
1304 pNodeBeforeAdjust = pPreNode;
1305 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
1306 pNodeBeforeDynamic = pPreNode;
1307 }
1308 if (pNode->mNext != NULL) {
1309 pPreNode = pNode;
1310 }
1311 OpcodeOffset += pNode->mBinBufLen;
1312 }
1313
1314 //
1315 // Check the nodes whether exist.
1316 //
1317 if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL) {
1318 return FALSE;
1319 }
1320
1321 //
1322 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1323 //
1324 pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;
1325 if (CreateOpcodeAfterParsingVfr) {
1326 //
1327 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1328 //
1329 mIfrRecordListTail->mNext = pAdjustNode;
1330 mIfrRecordListTail = pNodeBeforeDynamic;
1331 mIfrRecordListTail->mNext = NULL;
1332 } else {
1333 //
1334 //pPreNode is the end of pDynamicNode(Case1).
1335 //
1336 pPreNode->mNext = pAdjustNode;
1337 pNodeBeforeDynamic->mNext = mIfrRecordListTail;
1338 }
1339
1340 return TRUE;
1341 }
1342
1343 /**
1344 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1345
1346 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1347
1348 **/
1349 VOID
1350 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1351 IN BOOLEAN CreateOpcodeAfterParsingVfr
1352 )
1353 {
1354 SIfrRecord *pRecord;
1355
1356 //
1357 // Base on the original offset info to update the record list.
1358 //
1359 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {
1360 gCVfrErrorHandle.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");
1361 }
1362
1363 //
1364 // Base on the opcode binary length to recalculate the offset for each opcode.
1365 //
1366 IfrAdjustOffsetForRecord();
1367
1368 //
1369 // Base on the offset to find the binary address.
1370 //
1371 pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);
1372 while (pRecord != NULL) {
1373 pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);
1374 pRecord = pRecord->mNext;
1375 }
1376 }
1377
1378
1379 VOID
1380 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1381 VOID
1382 )
1383 {
1384 UINT32 OpcodeOffset;
1385 SIfrRecord *pNode;
1386
1387 OpcodeOffset = 0;
1388 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1389 pNode->mOffset = OpcodeOffset;
1390 OpcodeOffset += pNode->mBinBufLen;
1391 }
1392 }
1393
1394 EFI_VFR_RETURN_CODE
1395 CIfrRecordInfoDB::IfrRecordAdjust (
1396 VOID
1397 )
1398 {
1399 SIfrRecord *pNode, *preNode;
1400 SIfrRecord *uNode, *tNode;
1401 EFI_IFR_OP_HEADER *OpHead, *tOpHead;
1402 EFI_QUESTION_ID QuestionId;
1403 UINT32 StackCount;
1404 UINT32 QuestionScope;
1405 UINT32 OpcodeOffset;
1406 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
1407 EFI_VFR_RETURN_CODE Status;
1408
1409 //
1410 // Init local variable
1411 //
1412 Status = VFR_RETURN_SUCCESS;
1413 pNode = mIfrRecordListHead;
1414 preNode = pNode;
1415 QuestionScope = 0;
1416 while (pNode != NULL) {
1417 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
1418
1419 //
1420 // make sure the inconsistent opcode in question scope
1421 //
1422 if (QuestionScope > 0) {
1423 QuestionScope += OpHead->Scope;
1424 if (OpHead->OpCode == EFI_IFR_END_OP) {
1425 QuestionScope --;
1426 }
1427 }
1428
1429 if (CheckQuestionOpCode (OpHead->OpCode)) {
1430 QuestionScope = 1;
1431 }
1432 //
1433 // for the inconsistent opcode not in question scope, adjust it
1434 //
1435 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
1436 //
1437 // for inconsistent opcode not in question scope
1438 //
1439
1440 //
1441 // Count inconsistent opcode Scope
1442 //
1443 StackCount = OpHead->Scope;
1444 QuestionId = EFI_QUESTION_ID_INVALID;
1445 tNode = pNode;
1446 while (tNode != NULL && StackCount > 0) {
1447 tNode = tNode->mNext;
1448 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
1449 //
1450 // Calculate Scope Number
1451 //
1452 StackCount += tOpHead->Scope;
1453 if (tOpHead->OpCode == EFI_IFR_END_OP) {
1454 StackCount --;
1455 }
1456 //
1457 // by IdEqual opcode to get QuestionId
1458 //
1459 if (QuestionId == EFI_QUESTION_ID_INVALID &&
1460 CheckIdOpCode (tOpHead->OpCode)) {
1461 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
1462 }
1463 }
1464 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
1465 //
1466 // report error; not found
1467 //
1468 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
1469 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1470 Status = VFR_RETURN_MISMATCHED;
1471 break;
1472 }
1473 //
1474 // extract inconsistent opcode list
1475 // pNode is Incosistent opcode, tNode is End Opcode
1476 //
1477
1478 //
1479 // insert inconsistent opcode list into the right question scope by questionid
1480 //
1481 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
1482 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
1483 if (CheckQuestionOpCode (tOpHead->OpCode) &&
1484 (QuestionId == GetOpcodeQuestionId (tOpHead))) {
1485 break;
1486 }
1487 }
1488 //
1489 // insert inconsistent opcode list and check LATE_CHECK flag
1490 //
1491 if (uNode != NULL) {
1492 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
1493 //
1494 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1495 //
1496 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
1497 }
1498
1499 //
1500 // skip the default storage for Date and Time
1501 //
1502 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
1503 uNode = uNode->mNext;
1504 }
1505
1506 preNode->mNext = tNode->mNext;
1507 tNode->mNext = uNode->mNext;
1508 uNode->mNext = pNode;
1509 //
1510 // reset pNode to head list, scan the whole list again.
1511 //
1512 pNode = mIfrRecordListHead;
1513 preNode = pNode;
1514 QuestionScope = 0;
1515 continue;
1516 } else {
1517 //
1518 // not found matched question id, report error
1519 //
1520 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
1521 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1522 Status = VFR_RETURN_MISMATCHED;
1523 break;
1524 }
1525 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
1526 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
1527 //
1528 // for new added group of varstore opcode
1529 //
1530 tNode = pNode;
1531 while (tNode->mNext != NULL) {
1532 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
1533 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
1534 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
1535 break;
1536 }
1537 tNode = tNode->mNext;
1538 }
1539
1540 if (tNode->mNext == NULL) {
1541 //
1542 // invalid IfrCode, IfrCode end by EndOpCode
1543 //
1544 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
1545 Status = VFR_RETURN_MISMATCHED;
1546 break;
1547 }
1548
1549 if (tOpHead->OpCode != EFI_IFR_END_OP) {
1550 //
1551 // not new added varstore, which are not needed to be adjust.
1552 //
1553 preNode = tNode;
1554 pNode = tNode->mNext;
1555 continue;
1556 } else {
1557 //
1558 // move new added varstore opcode to the position befor form opcode
1559 // varstore opcode between pNode and tNode
1560 //
1561
1562 //
1563 // search form opcode from begin
1564 //
1565 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
1566 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
1567 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
1568 break;
1569 }
1570 }
1571 //
1572 // Insert varstore opcode beform form opcode if form opcode is found
1573 //
1574 if (uNode->mNext != NULL) {
1575 preNode->mNext = tNode->mNext;
1576 tNode->mNext = uNode->mNext;
1577 uNode->mNext = pNode;
1578 //
1579 // reset pNode to head list, scan the whole list again.
1580 //
1581 pNode = mIfrRecordListHead;
1582 preNode = pNode;
1583 QuestionScope = 0;
1584 continue;
1585 } else {
1586 //
1587 // not found form, continue scan IfrRecord list
1588 //
1589 preNode = tNode;
1590 pNode = tNode->mNext;
1591 continue;
1592 }
1593 }
1594 }
1595 //
1596 // next node
1597 //
1598 preNode = pNode;
1599 pNode = pNode->mNext;
1600 }
1601
1602 //
1603 // Update Ifr Opcode Offset
1604 //
1605 if (Status == VFR_RETURN_SUCCESS) {
1606 IfrAdjustOffsetForRecord ();
1607 }
1608 return Status;
1609 }
1610
1611 /**
1612 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1613 given by expression, should save the default info for the Buffer VarStore.
1614
1615 @param DefaultId The default id.
1616 @param pQuestionNode Point to the question opcode node.
1617 @param Value The default value.
1618 **/
1619 VOID
1620 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1621 IN UINT16 DefaultId,
1622 IN SIfrRecord *pQuestionNode,
1623 IN EFI_IFR_TYPE_VALUE Value
1624 )
1625 {
1626 CHAR8 *VarStoreName = NULL;
1627 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
1628 EFI_GUID *VarGuid = NULL;
1629 EFI_VARSTORE_INFO VarInfo;
1630 EFI_IFR_QUESTION_HEADER *QuestionHead;
1631 EFI_IFR_OP_HEADER *pQuestionOpHead;
1632
1633 pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
1634 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);
1635
1636 //
1637 // Get the Var Store name and type.
1638 //
1639 gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);
1640 VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);
1641 VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);
1642
1643 //
1644 // Only for Buffer storage need to save the default info in the storage.
1645 // Other type storage, just return.
1646 //
1647 if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {
1648 return;
1649 } else {
1650 VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;
1651 VarInfo.mVarStoreId = QuestionHead->VarStoreId;
1652 }
1653
1654 //
1655 // Get the buffer storage info about this question.
1656 //
1657 gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);
1658
1659 //
1660 // Add action.
1661 //
1662 gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
1663 DefaultId,
1664 VarInfo,
1665 VarStoreName,
1666 VarGuid,
1667 VarInfo.mVarType,
1668 Value
1669 );
1670 }
1671
1672 /**
1673 Record the number and default id of all defaultstore opcode.
1674
1675 **/
1676 VOID
1677 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1678 VOID
1679 )
1680 {
1681 SIfrRecord *pNode;
1682 EFI_IFR_OP_HEADER *pOpHead;
1683 EFI_IFR_DEFAULTSTORE *DefaultStore;
1684
1685 pNode = mIfrRecordListHead;
1686 mAllDefaultTypeCount = 0;
1687
1688 while (pNode != NULL) {
1689 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
1690
1691 if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){
1692 DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;
1693 mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;
1694 }
1695 pNode = pNode->mNext;
1696 }
1697 }
1698
1699 /**
1700 Create new default opcode record.
1701
1702 @param Size The new default opcode size.
1703 @param DefaultId The new default id.
1704 @param Type The new default type.
1705 @param LineNo The line number of the new record.
1706 @param Value The new default value.
1707
1708 **/
1709 VOID
1710 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1711 IN UINT8 Size,
1712 IN UINT16 DefaultId,
1713 IN UINT8 Type,
1714 IN UINT32 LineNo,
1715 IN EFI_IFR_TYPE_VALUE Value
1716 )
1717 {
1718 CIfrDefault *DObj;
1719 CIfrDefault2 *DObj2;
1720
1721 DObj = NULL;
1722 DObj2 = NULL;
1723
1724 if (Type == EFI_IFR_TYPE_OTHER) {
1725 DObj2 = new CIfrDefault2 (Size);
1726 DObj2->SetDefaultId(DefaultId);
1727 DObj2->SetType(Type);
1728 DObj2->SetLineNo(LineNo);
1729 DObj2->SetScope (1);
1730 delete DObj2;
1731 } else {
1732 DObj = new CIfrDefault (Size);
1733 DObj->SetDefaultId(DefaultId);
1734 DObj->SetType(Type);
1735 DObj->SetLineNo(LineNo);
1736 DObj->SetValue (Value);
1737 delete DObj;
1738 }
1739 }
1740
1741 /**
1742 Create new default opcode for question base on the QuestionDefaultInfo.
1743
1744 @param pQuestionNode Point to the question opcode Node.
1745 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1746
1747 **/
1748 VOID
1749 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1750 IN SIfrRecord *pQuestionNode,
1751 IN QuestionDefaultRecord *QuestionDefaultInfo
1752 )
1753 {
1754 EFI_IFR_OP_HEADER *pOpHead;
1755 EFI_IFR_DEFAULT *Default;
1756 SIfrRecord *pSNode;
1757 SIfrRecord *pENode;
1758 SIfrRecord *pDefaultNode;
1759 CIfrObj *Obj;
1760 CHAR8 *ObjBinBuf;
1761 UINT8 ScopeCount;
1762 UINT8 OpcodeNumber;
1763 UINT8 OpcodeCount;
1764 UINT8 DefaultSize;
1765 EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;
1766 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;
1767
1768 CheckBoxDefaultValue.b = 1;
1769 pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
1770 ScopeCount = 0;
1771 OpcodeCount = 0;
1772 Obj = NULL;
1773
1774 //
1775 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1776 //
1777 gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;
1778 //
1779 // Case 1:
1780 // For oneof, the default with smallest default id is given by the option flag.
1781 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1782 //
1783 if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
1784 DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;
1785 DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
1786 DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);
1787 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1788 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1789 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);
1790 //
1791 // Save the new created default in the buffer storage.
1792 //
1793 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);
1794 }
1795 }
1796 return;
1797 }
1798
1799 //
1800 // Case2:
1801 // For checkbox, the default with smallest default id is given by the question flag.
1802 // And create the missing defaults with true value.
1803 //
1804 if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
1805 DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);
1806 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1807 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1808 IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);
1809 //
1810 // Save the new created default.
1811 //
1812 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);
1813 }
1814 }
1815 return;
1816 }
1817
1818 //
1819 // Case3:
1820 // The default with smallest default id is given by the default opcode.
1821 // So create the missing defaults base on the value in the default opcode.
1822 //
1823
1824 //
1825 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1826 //
1827 pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;
1828 Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;
1829 //
1830 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1831 //
1832 gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;
1833
1834 if (Default->Type == EFI_IFR_TYPE_OTHER) {
1835 //
1836 // EFI_IFR_DEFAULT_2 opcode.
1837 //
1838 // Point to the first expression opcode.
1839 //
1840 pSNode = pDefaultNode->mNext;
1841 ScopeCount++;
1842 //
1843 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1844 //
1845 while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {
1846 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1847 if (pOpHead->Scope == 1) {
1848 ScopeCount++;
1849 }
1850 if (pOpHead->OpCode == EFI_IFR_END_OP) {
1851 ScopeCount--;
1852 }
1853 pENode = pSNode;
1854 pSNode = pSNode->mNext;
1855 OpcodeCount++;
1856 }
1857 //
1858 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1859 //
1860 gAdjustOpcodeOffset = pSNode->mOffset;
1861 //
1862 // Create new default opcode node for missing default.
1863 //
1864 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1865 OpcodeNumber = OpcodeCount;
1866 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1867 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);
1868 //
1869 // Point to the first expression opcode node.
1870 //
1871 pSNode = pDefaultNode->mNext;
1872 //
1873 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1874 //
1875 while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {
1876 pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1877 Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);
1878 Obj->SetLineNo (pSNode->mLineNo);
1879 ObjBinBuf = Obj->GetObjBinAddr();
1880 memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);
1881 delete Obj;
1882 pSNode = pSNode->mNext;
1883 }
1884 }
1885 }
1886 } else {
1887 //
1888 // EFI_IFR_DEFAULT opcode.
1889 //
1890 // Create new default opcode node for missing default.
1891 //
1892 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1893 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1894 IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);
1895 //
1896 // Save the new created default in the buffer storage..
1897 //
1898 IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);
1899 }
1900 }
1901 }
1902 }
1903
1904 /**
1905 Parse the default information in a question, get the QuestionDefaultInfo.
1906
1907 @param pQuestionNode Point to the question record Node.
1908 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1909 **/
1910 VOID
1911 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1912 IN SIfrRecord *pQuestionNode,
1913 OUT QuestionDefaultRecord *QuestionDefaultInfo
1914 )
1915 {
1916 SIfrRecord *pSNode;
1917 EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;
1918 EFI_IFR_OP_HEADER *pSOpHead;
1919 EFI_IFR_CHECKBOX *CheckBoxOpcode;
1920 EFI_IFR_DEFAULT *DefaultOpcode;
1921 BOOLEAN IsOneOfOpcode;
1922 UINT16 SmallestDefaultId;
1923 UINT8 ScopeCount;
1924
1925 SmallestDefaultId = 0xffff;
1926 IsOneOfOpcode = FALSE;
1927 ScopeCount = 0;
1928 pSNode = pQuestionNode;
1929
1930 //
1931 // Parse all the opcodes in the Question.
1932 //
1933 while (pSNode != NULL) {
1934 pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
1935 //
1936 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1937 // Scopes may be nested within other scopes.
1938 // When finishing parsing a question, the scope count must be zero.
1939 //
1940 if (pSOpHead->Scope == 1) {
1941 ScopeCount++;
1942 }
1943 if (pSOpHead->OpCode == EFI_IFR_END_OP) {
1944 ScopeCount--;
1945 }
1946 //
1947 // Check whether finishing parsing a question.
1948 //
1949 if (ScopeCount == 0) {
1950 break;
1951 }
1952
1953 //
1954 // Record the default information in the question.
1955 //
1956 switch (pSOpHead->OpCode) {
1957 case EFI_IFR_ONE_OF_OP:
1958 IsOneOfOpcode = TRUE;
1959 break;
1960 case EFI_IFR_CHECKBOX_OP:
1961 //
1962 // The default info of check box may be given by flag.
1963 // So need to check the flag of check box.
1964 //
1965 CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;
1966 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {
1967 //
1968 // Check whether need to update the smallest default id.
1969 //
1970 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
1971 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
1972 }
1973 //
1974 // Update the QuestionDefaultInfo.
1975 //
1976 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1977 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
1978 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1979 QuestionDefaultInfo->mDefaultNumber ++;
1980 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
1981 }
1982 break;
1983 }
1984 }
1985 }
1986 if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {
1987 //
1988 // Check whether need to update the smallest default id.
1989 //
1990 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
1991 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
1992 }
1993 //
1994 // Update the QuestionDefaultInfo.
1995 //
1996 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
1997 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
1998 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
1999 QuestionDefaultInfo->mDefaultNumber ++;
2000 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2001 }
2002 break;
2003 }
2004 }
2005 }
2006 break;
2007 case EFI_IFR_ONE_OF_OPTION_OP:
2008 if (!IsOneOfOpcode) {
2009 //
2010 // Only check the option in oneof.
2011 //
2012 break;
2013 }
2014 OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;
2015 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
2016 //
2017 // The option is used as the standard default.
2018 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2019 //
2020 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
2021 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2022 QuestionDefaultInfo->mDefaultValueRecord = pSNode;
2023 }
2024 //
2025 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2026 //
2027 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
2028 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
2029 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2030 QuestionDefaultInfo->mDefaultNumber ++;
2031 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2032 }
2033 break;
2034 }
2035 }
2036 }
2037 if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {
2038 //
2039 // This option is used as the manufacture default.
2040 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2041 //
2042 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2043 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2044 QuestionDefaultInfo->mDefaultValueRecord = pSNode;
2045 }
2046 //
2047 // Update the QuestionDefaultInfo.
2048 //
2049 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
2050 if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2051 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2052 QuestionDefaultInfo->mDefaultNumber ++;
2053 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2054 }
2055 break;
2056 }
2057 }
2058 }
2059 break;
2060 case EFI_IFR_DEFAULT_OP:
2061 DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;
2062 //
2063 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2064 //
2065 if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {
2066 SmallestDefaultId = DefaultOpcode->DefaultId;
2067 QuestionDefaultInfo->mDefaultValueRecord= pSNode;
2068 QuestionDefaultInfo->mIsDefaultOpcode= TRUE;
2069 }
2070 //
2071 // Update the QuestionDefaultInfo.
2072 //
2073 for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){
2074 if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {
2075 if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
2076 QuestionDefaultInfo->mDefaultNumber ++;
2077 QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
2078 }
2079 break;
2080 }
2081 }
2082 break;
2083 default:
2084 break;
2085 }
2086 //
2087 // Parse next opcode in this question.
2088 //
2089 pSNode = pSNode->mNext;
2090 }
2091 }
2092
2093 /**
2094 Check or add default for question if need.
2095
2096 This function will check the default info for question.
2097 If the question has default, but the default number < defaultstore opcode number.
2098 will do following two action :
2099
2100 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2101 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2102
2103 We assume that the two options can not be TRUE at same time.
2104 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2105
2106 @param AutoDefault Add default for question if needed
2107 @param CheckDefault Check the default info, if missing default, generates an error.
2108
2109 **/
2110 VOID
2111 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2112 BOOLEAN AutoDefault,
2113 BOOLEAN CheckDefault
2114 )
2115 {
2116 SIfrRecord *pNode;
2117 SIfrRecord *pTailNode;
2118 SIfrRecord *pStartAdjustNode;
2119 EFI_IFR_OP_HEADER *pOpHead;
2120 QuestionDefaultRecord QuestionDefaultInfo;
2121 UINT8 MissingDefaultCount;
2122 CHAR8 Msg[MAX_STRING_LEN] = {0, };
2123
2124 pNode = mIfrRecordListHead;
2125
2126 //
2127 // Record the number and default id of all defaultstore opcode.
2128 //
2129 IfrGetDefaultStoreInfo ();
2130
2131 while (pNode != NULL) {
2132 pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
2133 //
2134 // Check whether is question opcode.
2135 //
2136 if (CheckQuestionOpCode (pOpHead->OpCode)) {
2137 //
2138 // Initialize some local variables here, because they vary with question.
2139 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2140 //
2141 memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));
2142 pTailNode = mIfrRecordListTail;
2143 //
2144 // Get the QuestionDefaultInfo for current question.
2145 //
2146 IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);
2147
2148 if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {
2149 if (AutoDefault) {
2150 //
2151 // Create default for question which misses default.
2152 //
2153 IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);
2154
2155 //
2156 // Adjust the buffer content.
2157 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2158 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2159 //
2160 pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);
2161 gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);
2162
2163 //
2164 // Update the record info.
2165 //
2166 IfrUpdateRecordInfoForDynamicOpcode (TRUE);
2167 } else if (CheckDefault) {
2168 //
2169 // Generate an error for question which misses default.
2170 //
2171 MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;
2172 sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);
2173 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);
2174 }
2175 }
2176 }
2177 //
2178 // parse next opcode.
2179 //
2180 pNode = pNode->mNext;
2181 }
2182 }
2183
2184 CIfrRecordInfoDB gCIfrRecordInfoDB;
2185
2186 VOID
2187 CIfrObj::_EMIT_PENDING_OBJ (
2188 VOID
2189 )
2190 {
2191 CHAR8 *ObjBinBuf = NULL;
2192
2193 //
2194 // do nothing
2195 //
2196 if (!mDelayEmit || !gCreateOp) {
2197 return;
2198 }
2199
2200 mPkgOffset = gCFormPkg.GetPkgLength ();
2201 //
2202 // update data buffer to package data
2203 //
2204 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
2205 if (ObjBinBuf != NULL) {
2206 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
2207 }
2208
2209 //
2210 // update bin buffer to package data buffer
2211 //
2212 if (mObjBinBuf != NULL) {
2213 delete mObjBinBuf;
2214 mObjBinBuf = ObjBinBuf;
2215 }
2216
2217 mDelayEmit = FALSE;
2218 }
2219
2220 /*
2221 * The definition of CIfrObj's member function
2222 */
2223 static struct {
2224 UINT8 mSize;
2225 UINT8 mScope;
2226 } gOpcodeSizesScopeTable[] = {
2227 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2228 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
2229 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
2230 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
2231 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
2232 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2233 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
2234 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
2235 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
2236 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2237 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2238 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
2239 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
2240 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
2241 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2242 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
2243 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2244 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2245 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2246 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
2247 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2248 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
2249 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
2250 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
2251 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
2252 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2253 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
2254 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
2255 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
2256 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
2257 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2258 { 0, 0 }, // 0x1F
2259 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2260 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2261 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
2262 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2263 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
2264 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2265 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2266 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2267 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
2268 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
2269 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2270 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
2271 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
2272 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
2273 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
2274 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2275 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
2276 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
2277 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2278 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
2279 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2280 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
2281 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
2282 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
2283 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2284 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2285 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
2286 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
2287 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
2288 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
2289 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2290 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
2291 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
2292 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2293 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
2294 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
2295 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
2296 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
2297 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
2298 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
2299 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
2300 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
2301 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2302 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
2303 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
2304 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
2305 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2306 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
2307 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
2308 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
2309 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
2310 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
2311 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
2312 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
2313 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
2314 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
2315 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
2316 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
2317 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
2318 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
2319 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2320 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2321 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
2322 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
2323 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2324 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2325 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2326 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2327 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2328 };
2329
2330 #ifdef CIFROBJ_DEUBG
2331 static struct {
2332 CHAR8 *mIfrName;
2333 } gIfrObjPrintDebugTable[] = {
2334 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2335 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2336 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2337 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2338 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2339 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2340 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2341 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2342 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2343 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2344 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2345 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2346 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2347 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2348 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2349 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2350 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2351 };
2352
2353 VOID
2354 CIFROBJ_DEBUG_PRINT (
2355 IN UINT8 OpCode
2356 )
2357 {
2358 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
2359 }
2360 #else
2361
2362 #define CIFROBJ_DEBUG_PRINT(OpCode)
2363
2364 #endif
2365
2366 BOOLEAN gCreateOp = TRUE;
2367
2368 CIfrObj::CIfrObj (
2369 IN UINT8 OpCode,
2370 OUT CHAR8 **IfrObj,
2371 IN UINT8 ObjBinLen,
2372 IN BOOLEAN DelayEmit
2373 )
2374 {
2375 mDelayEmit = DelayEmit;
2376 mPkgOffset = gCFormPkg.GetPkgLength ();
2377 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
2378 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
2379 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
2380
2381 if (IfrObj != NULL) {
2382 *IfrObj = mObjBinBuf;
2383 }
2384
2385 CIFROBJ_DEBUG_PRINT (OpCode);
2386 }
2387
2388 CIfrObj::~CIfrObj (
2389 VOID
2390 )
2391 {
2392 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
2393 _EMIT_PENDING_OBJ ();
2394 }
2395
2396 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
2397 }
2398
2399 /*
2400 * The definition of CIfrObj's member function
2401 */
2402 UINT8 gScopeCount = 0;
2403
2404 CIfrOpHeader::CIfrOpHeader (
2405 IN UINT8 OpCode,
2406 IN VOID *StartAddr,
2407 IN UINT8 Length
2408 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
2409 {
2410 mHeader->OpCode = OpCode;
2411 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
2412 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
2413 }
2414
2415 CIfrOpHeader::CIfrOpHeader (
2416 IN CIfrOpHeader &OpHdr
2417 )
2418 {
2419 mHeader = OpHdr.mHeader;
2420 }
2421
2422 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };