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