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