1 /** @file 2 3 The definition of CFormPkg's member function 4 5 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "stdio.h" 17 #include "VfrFormPkg.h" 18 19 /* 20 * The definition of CFormPkg's member function 21 */ 22 23 SPendingAssign::SPendingAssign ( 24 IN CHAR8 *Key, 25 IN VOID *Addr, 26 IN UINT32 Len, 27 IN UINT32 LineNo, 28 IN CONST CHAR8 *Msg 29 ) 30 { 31 mKey = NULL; 32 mAddr = Addr; 33 mLen = Len; 34 mFlag = PENDING; 35 mLineNo = LineNo; 36 mMsg = NULL; 37 mNext = NULL; 38 if (Key != NULL) { 39 mKey = new CHAR8[strlen (Key) + 1]; 40 if (mKey != NULL) { 41 strcpy (mKey, Key); 42 } 43 } 44 45 if (Msg != NULL) { 46 mMsg = new CHAR8[strlen (Msg) + 1]; 47 if (mMsg != NULL) { 48 strcpy (mMsg, Msg); 49 } 50 } 51 } 52 53 SPendingAssign::~SPendingAssign ( 54 VOID 55 ) 56 { 57 if (mKey != NULL) { 58 delete mKey; 59 } 60 mAddr = NULL; 61 mLen = 0; 62 mLineNo = 0; 63 if (mMsg != NULL) { 64 delete mMsg; 65 } 66 mNext = NULL; 67 } 68 69 VOID 70 SPendingAssign::SetAddrAndLen ( 71 IN VOID *Addr, 72 IN UINT32 LineNo 73 ) 74 { 75 mAddr = Addr; 76 mLineNo = LineNo; 77 } 78 79 VOID 80 SPendingAssign::AssignValue ( 81 IN VOID *Addr, 82 IN UINT32 Len 83 ) 84 { 85 memmove (mAddr, Addr, (mLen < Len ? mLen : Len)); 86 mFlag = ASSIGNED; 87 } 88 89 CHAR8 * 90 SPendingAssign::GetKey ( 91 VOID 92 ) 93 { 94 return mKey; 95 } 96 97 CFormPkg::CFormPkg ( 98 IN UINT32 BufferSize 99 ) 100 { 101 CHAR8 *BufferStart; 102 CHAR8 *BufferEnd; 103 SBufferNode *Node; 104 105 mPkgLength = 0; 106 mBufferNodeQueueHead = NULL; 107 mCurrBufferNode = NULL; 108 109 Node = new SBufferNode; 110 if (Node == NULL) { 111 return ; 112 } 113 BufferStart = new CHAR8[BufferSize]; 114 if (BufferStart == NULL) { 115 return; 116 } 117 BufferEnd = BufferStart + BufferSize; 118 119 memset (BufferStart, 0, BufferSize); 120 Node->mBufferStart = BufferStart; 121 Node->mBufferEnd = BufferEnd; 122 Node->mBufferFree = BufferStart; 123 Node->mNext = NULL; 124 125 mBufferSize = BufferSize; 126 mBufferNodeQueueHead = Node; 127 mBufferNodeQueueTail = Node; 128 mCurrBufferNode = Node; 129 } 130 131 CFormPkg::~CFormPkg () 132 { 133 SBufferNode *pBNode; 134 SPendingAssign *pPNode; 135 136 while (mBufferNodeQueueHead != NULL) { 137 pBNode = mBufferNodeQueueHead; 138 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext; 139 if (pBNode->mBufferStart != NULL) { 140 delete pBNode->mBufferStart; 141 delete pBNode; 142 } 143 } 144 mBufferNodeQueueTail = NULL; 145 mCurrBufferNode = NULL; 146 147 while (PendingAssignList != NULL) { 148 pPNode = PendingAssignList; 149 PendingAssignList = PendingAssignList->mNext; 150 delete pPNode; 151 } 152 PendingAssignList = NULL; 153 } 154 155 SBufferNode * 156 CFormPkg::CreateNewNode ( 157 VOID 158 ) 159 { 160 SBufferNode *Node; 161 162 Node = new SBufferNode; 163 if (Node == NULL) { 164 return NULL; 165 } 166 167 Node->mBufferStart = new CHAR8[mBufferSize]; 168 if (Node->mBufferStart == NULL) { 169 delete Node; 170 return NULL; 171 } else { 172 memset (Node->mBufferStart, 0, mBufferSize); 173 Node->mBufferEnd = Node->mBufferStart + mBufferSize; 174 Node->mBufferFree = Node->mBufferStart; 175 Node->mNext = NULL; 176 } 177 178 return Node; 179 } 180 181 CHAR8 * 182 CFormPkg::IfrBinBufferGet ( 183 IN UINT32 Len 184 ) 185 { 186 CHAR8 *BinBuffer = NULL; 187 SBufferNode *Node = NULL; 188 189 if ((Len == 0) || (Len > mBufferSize)) { 190 return NULL; 191 } 192 193 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) { 194 BinBuffer = mCurrBufferNode->mBufferFree; 195 mCurrBufferNode->mBufferFree += Len; 196 } else { 197 Node = CreateNewNode (); 198 if (Node == NULL) { 199 return NULL; 200 } 201 202 if (mBufferNodeQueueTail == NULL) { 203 mBufferNodeQueueHead = mBufferNodeQueueTail = Node; 204 } else { 205 mBufferNodeQueueTail->mNext = Node; 206 mBufferNodeQueueTail = Node; 207 } 208 mCurrBufferNode = Node; 209 210 // 211 // Now try again. 212 // 213 BinBuffer = mCurrBufferNode->mBufferFree; 214 mCurrBufferNode->mBufferFree += Len; 215 } 216 217 mPkgLength += Len; 218 219 return BinBuffer; 220 } 221 222 inline 223 UINT32 224 CFormPkg::GetPkgLength ( 225 VOID 226 ) 227 { 228 return mPkgLength; 229 } 230 231 VOID 232 CFormPkg::Open ( 233 VOID 234 ) 235 { 236 mReadBufferNode = mBufferNodeQueueHead; 237 mReadBufferOffset = 0; 238 } 239 240 VOID 241 CFormPkg::Close ( 242 VOID 243 ) 244 { 245 mReadBufferNode = NULL; 246 mReadBufferOffset = 0; 247 } 248 249 UINT32 250 CFormPkg::Read ( 251 IN CHAR8 *Buffer, 252 IN UINT32 Size 253 ) 254 { 255 UINT32 Index; 256 257 if ((Size == 0) || (Buffer == NULL)) { 258 return 0; 259 } 260 261 if (mReadBufferNode == NULL) { 262 return 0; 263 } 264 265 for (Index = 0; Index < Size; Index++) { 266 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) { 267 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++]; 268 } else { 269 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) { 270 return Index; 271 } else { 272 mReadBufferOffset = 0; 273 Index --; 274 } 275 } 276 } 277 278 return Size; 279 } 280 281 EFI_VFR_RETURN_CODE 282 CFormPkg::BuildPkgHdr ( 283 OUT EFI_HII_PACKAGE_HEADER **PkgHdr 284 ) 285 { 286 if (PkgHdr == NULL) { 287 return VFR_RETURN_FATAL_ERROR; 288 } 289 290 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) { 291 return VFR_RETURN_OUT_FOR_RESOURCES; 292 } 293 294 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM; 295 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER); 296 297 return VFR_RETURN_SUCCESS; 298 } 299 300 EFI_VFR_RETURN_CODE 301 CFormPkg::BuildPkg ( 302 OUT PACKAGE_DATA &TBuffer 303 ) 304 { 305 306 CHAR8 *Temp; 307 UINT32 Size; 308 CHAR8 Buffer[1024]; 309 310 if (TBuffer.Buffer != NULL) { 311 delete TBuffer.Buffer; 312 } 313 314 TBuffer.Size = mPkgLength; 315 TBuffer.Buffer = NULL; 316 if (TBuffer.Size != 0) { 317 TBuffer.Buffer = new CHAR8[TBuffer.Size]; 318 } else { 319 return VFR_RETURN_SUCCESS; 320 } 321 322 Temp = TBuffer.Buffer; 323 Open (); 324 while ((Size = Read (Buffer, 1024)) != 0) { 325 memcpy (Temp, Buffer, Size); 326 Temp += Size; 327 } 328 Close (); 329 return VFR_RETURN_SUCCESS; 330 } 331 332 333 EFI_VFR_RETURN_CODE 334 CFormPkg::BuildPkg ( 335 IN FILE *Output, 336 IN PACKAGE_DATA *PkgData 337 ) 338 { 339 EFI_VFR_RETURN_CODE Ret; 340 CHAR8 Buffer[1024]; 341 UINT32 Size; 342 EFI_HII_PACKAGE_HEADER *PkgHdr; 343 344 if (Output == NULL) { 345 return VFR_RETURN_FATAL_ERROR; 346 } 347 348 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { 349 return Ret; 350 } 351 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output); 352 delete PkgHdr; 353 354 if (PkgData == NULL) { 355 Open (); 356 while ((Size = Read (Buffer, 1024)) != 0) { 357 fwrite (Buffer, Size, 1, Output); 358 } 359 Close (); 360 } else { 361 fwrite (PkgData->Buffer, PkgData->Size, 1, Output); 362 } 363 364 return VFR_RETURN_SUCCESS; 365 } 366 367 VOID 368 CFormPkg::_WRITE_PKG_LINE ( 369 IN FILE *pFile, 370 IN UINT32 LineBytes, 371 IN CONST CHAR8 *LineHeader, 372 IN CHAR8 *BlkBuf, 373 IN UINT32 BlkSize 374 ) 375 { 376 UINT32 Index; 377 378 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 379 return; 380 } 381 382 for (Index = 0; Index < BlkSize; Index++) { 383 if ((Index % LineBytes) == 0) { 384 fprintf (pFile, "\n%s", LineHeader); 385 } 386 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 387 } 388 } 389 390 VOID 391 CFormPkg::_WRITE_PKG_END ( 392 IN FILE *pFile, 393 IN UINT32 LineBytes, 394 IN CONST CHAR8 *LineHeader, 395 IN CHAR8 *BlkBuf, 396 IN UINT32 BlkSize 397 ) 398 { 399 UINT32 Index; 400 401 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 402 return; 403 } 404 405 for (Index = 0; Index < BlkSize - 1; Index++) { 406 if ((Index % LineBytes) == 0) { 407 fprintf (pFile, "\n%s", LineHeader); 408 } 409 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 410 } 411 412 if ((Index % LineBytes) == 0) { 413 fprintf (pFile, "\n%s", LineHeader); 414 } 415 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); 416 } 417 418 #define BYTES_PRE_LINE 0x10 419 UINT32 gAdjustOpcodeOffset = 0; 420 BOOLEAN gNeedAdjustOpcode = FALSE; 421 UINT32 gAdjustOpcodeLen = 0; 422 423 EFI_VFR_RETURN_CODE 424 CFormPkg::GenCFile ( 425 IN CHAR8 *BaseName, 426 IN FILE *pFile, 427 IN PACKAGE_DATA *PkgData 428 ) 429 { 430 EFI_VFR_RETURN_CODE Ret; 431 CHAR8 Buffer[BYTES_PRE_LINE * 8]; 432 EFI_HII_PACKAGE_HEADER *PkgHdr; 433 UINT32 PkgLength = 0; 434 UINT32 ReadSize = 0; 435 436 if ((BaseName == NULL) || (pFile == NULL)) { 437 return VFR_RETURN_FATAL_ERROR; 438 } 439 440 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName); 441 442 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { 443 return Ret; 444 } 445 446 // 447 // For framework vfr file, the extension framework header will be added. 448 // 449 if (VfrCompatibleMode) { 450 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n"); 451 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2; 452 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); 453 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n"); 454 PkgLength = 3; 455 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16)); 456 } else { 457 fprintf (pFile, " // ARRAY LENGTH\n"); 458 PkgLength = PkgHdr->Length + sizeof (UINT32); 459 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); 460 } 461 462 fprintf (pFile, "\n\n // PACKAGE HEADER\n"); 463 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 464 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER); 465 466 fprintf (pFile, "\n\n // PACKAGE DATA\n"); 467 468 if (PkgData == NULL) { 469 Open (); 470 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) { 471 PkgLength += ReadSize; 472 if (PkgLength < PkgHdr->Length) { 473 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); 474 } else { 475 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); 476 } 477 } 478 Close (); 479 } else { 480 if (PkgData->Size % BYTES_PRE_LINE != 0) { 481 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE); 482 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength); 483 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE); 484 } else { 485 PkgLength = PkgData->Size - BYTES_PRE_LINE; 486 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength); 487 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE); 488 } 489 } 490 491 delete PkgHdr; 492 fprintf (pFile, "\n};\n"); 493 494 return VFR_RETURN_SUCCESS; 495 } 496 497 EFI_VFR_RETURN_CODE 498 CFormPkg::AssignPending ( 499 IN CHAR8 *Key, 500 IN VOID *ValAddr, 501 IN UINT32 ValLen, 502 IN UINT32 LineNo, 503 IN CONST CHAR8 *Msg 504 ) 505 { 506 SPendingAssign *pNew; 507 508 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg); 509 if (pNew == NULL) { 510 return VFR_RETURN_OUT_FOR_RESOURCES; 511 } 512 513 pNew->mNext = PendingAssignList; 514 PendingAssignList = pNew; 515 return VFR_RETURN_SUCCESS; 516 } 517 518 VOID 519 CFormPkg::DoPendingAssign ( 520 IN CHAR8 *Key, 521 IN VOID *ValAddr, 522 IN UINT32 ValLen 523 ) 524 { 525 SPendingAssign *pNode; 526 527 if ((Key == NULL) || (ValAddr == NULL)) { 528 return; 529 } 530 531 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 532 if (strcmp (pNode->mKey, Key) == 0) { 533 pNode->AssignValue (ValAddr, ValLen); 534 } 535 } 536 } 537 538 bool 539 CFormPkg::HavePendingUnassigned ( 540 VOID 541 ) 542 { 543 SPendingAssign *pNode; 544 545 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 546 if (pNode->mFlag == PENDING) { 547 return TRUE; 548 } 549 } 550 551 return FALSE; 552 } 553 554 VOID 555 CFormPkg::PendingAssignPrintAll ( 556 VOID 557 ) 558 { 559 SPendingAssign *pNode; 560 561 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 562 if (pNode->mFlag == PENDING) { 563 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg); 564 } 565 } 566 } 567 568 SBufferNode * 569 CFormPkg::GetBinBufferNodeForAddr ( 570 IN CHAR8 *BinBuffAddr 571 ) 572 { 573 SBufferNode *TmpNode; 574 575 TmpNode = mBufferNodeQueueHead; 576 577 while (TmpNode != NULL) { 578 if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) { 579 return TmpNode; 580 } 581 582 TmpNode = TmpNode->mNext; 583 } 584 585 return NULL; 586 } 587 588 SBufferNode * 589 CFormPkg::GetNodeBefore( 590 IN SBufferNode *CurrentNode 591 ) 592 { 593 SBufferNode *FirstNode = mBufferNodeQueueHead; 594 SBufferNode *LastNode = mBufferNodeQueueHead; 595 596 while (FirstNode != NULL) { 597 if (FirstNode == CurrentNode) { 598 break; 599 } 600 601 LastNode = FirstNode; 602 FirstNode = FirstNode->mNext; 603 } 604 605 if (FirstNode == NULL) { 606 LastNode = NULL; 607 } 608 609 return LastNode; 610 } 611 612 EFI_VFR_RETURN_CODE 613 CFormPkg::InsertNodeBefore( 614 IN SBufferNode *CurrentNode, 615 IN SBufferNode *NewNode 616 ) 617 { 618 SBufferNode *LastNode = GetNodeBefore (CurrentNode); 619 620 if (LastNode == NULL) { 621 return VFR_RETURN_MISMATCHED; 622 } 623 624 NewNode->mNext = LastNode->mNext; 625 LastNode->mNext = NewNode; 626 627 return VFR_RETURN_SUCCESS; 628 } 629 630 CHAR8 * 631 CFormPkg::GetBufAddrBaseOnOffset ( 632 IN UINT32 Offset 633 ) 634 { 635 SBufferNode *TmpNode; 636 UINT32 TotalBufLen; 637 UINT32 CurrentBufLen; 638 639 TotalBufLen = 0; 640 641 for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) { 642 CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart; 643 if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) { 644 return TmpNode->mBufferStart + (Offset - TotalBufLen); 645 } 646 647 TotalBufLen += CurrentBufLen; 648 } 649 650 return NULL; 651 } 652 653 EFI_VFR_RETURN_CODE 654 CFormPkg::AdjustDynamicInsertOpcode ( 655 IN CHAR8 *LastFormEndAddr, 656 IN CHAR8 *InsertOpcodeAddr 657 ) 658 { 659 SBufferNode *LastFormEndNode; 660 SBufferNode *InsertOpcodeNode; 661 SBufferNode *NewRestoreNodeBegin; 662 SBufferNode *NewRestoreNodeEnd; 663 SBufferNode *NewLastEndNode; 664 SBufferNode *TmpNode; 665 UINT32 NeedRestoreCodeLen; 666 667 NewRestoreNodeEnd = NULL; 668 669 LastFormEndNode = GetBinBufferNodeForAddr(LastFormEndAddr); 670 InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr); 671 672 if (LastFormEndNode == InsertOpcodeNode) { 673 // 674 // Create New Node to save the restore opcode. 675 // 676 NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr; 677 gAdjustOpcodeLen = NeedRestoreCodeLen; 678 NewRestoreNodeBegin = CreateNewNode (); 679 if (NewRestoreNodeBegin == NULL) { 680 return VFR_RETURN_OUT_FOR_RESOURCES; 681 } 682 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen); 683 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen; 684 685 // 686 // Override the restore buffer data. 687 // 688 memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); 689 InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen; 690 memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen); 691 } else { 692 // 693 // Create New Node to save the restore opcode. 694 // 695 NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr; 696 gAdjustOpcodeLen = NeedRestoreCodeLen; 697 NewRestoreNodeBegin = CreateNewNode (); 698 if (NewRestoreNodeBegin == NULL) { 699 return VFR_RETURN_OUT_FOR_RESOURCES; 700 } 701 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen); 702 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen; 703 // 704 // Override the restore buffer data. 705 // 706 LastFormEndNode->mBufferFree -= NeedRestoreCodeLen; 707 // 708 // Link the restore data to new node. 709 // 710 NewRestoreNodeBegin->mNext = LastFormEndNode->mNext; 711 712 // 713 // Count the Adjust opcode len. 714 // 715 TmpNode = LastFormEndNode->mNext; 716 while (TmpNode != InsertOpcodeNode) { 717 gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart; 718 TmpNode = TmpNode->mNext; 719 } 720 721 // 722 // Create New Node to save the last node of restore opcode. 723 // 724 NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart; 725 gAdjustOpcodeLen += NeedRestoreCodeLen; 726 if (NeedRestoreCodeLen > 0) { 727 NewRestoreNodeEnd = CreateNewNode (); 728 if (NewRestoreNodeEnd == NULL) { 729 return VFR_RETURN_OUT_FOR_RESOURCES; 730 } 731 memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen); 732 NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen; 733 // 734 // Override the restore buffer data. 735 // 736 memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr); 737 InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart; 738 739 // 740 // Insert the last restore data node. 741 // 742 TmpNode = GetNodeBefore (InsertOpcodeNode); 743 if (TmpNode == LastFormEndNode) { 744 NewRestoreNodeBegin->mNext = NewRestoreNodeEnd; 745 } else { 746 TmpNode->mNext = NewRestoreNodeEnd; 747 } 748 // 749 // Connect the dynamic opcode node to the node before last form end node. 750 // 751 LastFormEndNode->mNext = InsertOpcodeNode; 752 } 753 } 754 755 if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) { 756 // 757 // End form set opcode all in the mBufferNodeQueueTail node. 758 // 759 NewLastEndNode = CreateNewNode (); 760 if (NewLastEndNode == NULL) { 761 return VFR_RETURN_OUT_FOR_RESOURCES; 762 } 763 NewLastEndNode->mBufferStart[0] = 0x29; 764 NewLastEndNode->mBufferStart[1] = 0x02; 765 NewLastEndNode->mBufferFree += 2; 766 767 mBufferNodeQueueTail->mBufferFree -= 2; 768 769 mBufferNodeQueueTail->mNext = NewRestoreNodeBegin; 770 if (NewRestoreNodeEnd != NULL) { 771 NewRestoreNodeEnd->mNext = NewLastEndNode; 772 } else { 773 NewRestoreNodeBegin->mNext = NewLastEndNode; 774 } 775 776 mBufferNodeQueueTail = NewLastEndNode; 777 } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) { 778 TmpNode = GetNodeBefore(mBufferNodeQueueTail); 779 TmpNode->mNext = NewRestoreNodeBegin; 780 if (NewRestoreNodeEnd != NULL) { 781 NewRestoreNodeEnd->mNext = mBufferNodeQueueTail; 782 } else { 783 NewRestoreNodeBegin->mNext = mBufferNodeQueueTail; 784 } 785 } 786 787 return VFR_RETURN_SUCCESS; 788 } 789 790 EFI_VFR_RETURN_CODE 791 CFormPkg::DeclarePendingQuestion ( 792 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB, 793 IN CVfrDataStorage &lCVfrDataStorage, 794 IN CVfrQuestionDB &lCVfrQuestionDB, 795 IN EFI_GUID *LocalFormSetGuid, 796 IN UINT32 LineNo, 797 OUT CHAR8 **InsertOpcodeAddr 798 ) 799 { 800 SPendingAssign *pNode; 801 CHAR8 *VarStr; 802 UINT32 ArrayIdx; 803 CHAR8 FName[MAX_NAME_LEN]; 804 CHAR8 *SName; 805 CHAR8 *NewStr; 806 UINT32 ShrinkSize; 807 EFI_VFR_RETURN_CODE ReturnCode; 808 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID; 809 EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID; 810 811 // 812 // Declare all questions as Numeric in DisableIf True 813 // 814 // DisableIf 815 CIfrDisableIf DIObj; 816 DIObj.SetLineNo (LineNo); 817 *InsertOpcodeAddr = DIObj.GetObjBinAddr (); 818 819 //TrueOpcode 820 CIfrTrue TObj (LineNo); 821 822 // Declare Numeric qeustion for each undefined question. 823 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 824 if (pNode->mFlag == PENDING) { 825 CIfrNumeric CNObj; 826 EFI_VARSTORE_INFO Info; 827 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID; 828 829 CNObj.SetLineNo (LineNo); 830 CNObj.SetPrompt (0x0); 831 CNObj.SetHelp (0x0); 832 833 // 834 // Register this question, assume it is normal question, not date or time question 835 // 836 VarStr = pNode->mKey; 837 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId); 838 if (ReturnCode != VFR_RETURN_SUCCESS) { 839 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey); 840 return ReturnCode; 841 } 842 843 #ifdef VFREXP_DEBUG 844 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId); 845 #endif 846 // 847 // Get Question Info, framework vfr VarName == StructName 848 // 849 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx); 850 if (ReturnCode != VFR_RETURN_SUCCESS) { 851 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable"); 852 return ReturnCode; 853 } 854 // 855 // Get VarStoreType 856 // 857 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId); 858 if (ReturnCode != VFR_RETURN_SUCCESS) { 859 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined"); 860 return ReturnCode; 861 } 862 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); 863 864 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) { 865 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx); 866 } else { 867 if (VarStoreType == EFI_VFR_VARSTORE_EFI) { 868 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info); 869 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) { 870 VarStr = pNode->mKey; 871 //convert VarStr with store name to VarStr with structure name 872 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName); 873 if (ReturnCode == VFR_RETURN_SUCCESS) { 874 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1]; 875 NewStr[0] = '\0'; 876 strcpy (NewStr, SName); 877 strcat (NewStr, VarStr + strlen (FName)); 878 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize); 879 delete NewStr; 880 } 881 } else { 882 ReturnCode = VFR_RETURN_UNSUPPORTED; 883 } 884 } 885 if (ReturnCode != VFR_RETURN_SUCCESS) { 886 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey); 887 return ReturnCode; 888 } 889 890 CNObj.SetQuestionId (QId); 891 CNObj.SetVarStoreInfo (&Info); 892 // 893 // Numeric doesn't support BOOLEAN data type. 894 // BOOLEAN type has the same data size to UINT8. 895 // 896 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) { 897 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8; 898 } 899 CNObj.SetFlags (0, Info.mVarType); 900 // 901 // Use maximum value not to limit the vaild value for the undefined question. 902 // 903 switch (Info.mVarType) { 904 case EFI_IFR_TYPE_NUM_SIZE_64: 905 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0); 906 ShrinkSize = 0; 907 break; 908 case EFI_IFR_TYPE_NUM_SIZE_32: 909 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0); 910 ShrinkSize = 12; 911 break; 912 case EFI_IFR_TYPE_NUM_SIZE_16: 913 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0); 914 ShrinkSize = 18; 915 break; 916 case EFI_IFR_TYPE_NUM_SIZE_8: 917 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0); 918 ShrinkSize = 21; 919 break; 920 default: 921 break; 922 } 923 CNObj.ShrinkBinSize (ShrinkSize); 924 925 // 926 // For undefined Efi VarStore type question 927 // Append the extended guided opcode to contain VarName 928 // 929 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) { 930 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName); 931 CVNObj.SetLineNo (LineNo); 932 } 933 934 // 935 // End for Numeric 936 // 937 CIfrEnd CEObj; 938 CEObj.SetLineNo (LineNo); 939 } 940 } 941 942 // 943 // End for DisableIf 944 // 945 CIfrEnd SEObj; 946 SEObj.SetLineNo (LineNo); 947 948 return VFR_RETURN_SUCCESS; 949 } 950 951 CFormPkg gCFormPkg; 952 953 SIfrRecord::SIfrRecord ( 954 VOID 955 ) 956 { 957 mIfrBinBuf = NULL; 958 mBinBufLen = 0; 959 mLineNo = 0xFFFFFFFF; 960 mOffset = 0xFFFFFFFF; 961 mNext = NULL; 962 } 963 964 SIfrRecord::~SIfrRecord ( 965 VOID 966 ) 967 { 968 if (mIfrBinBuf != NULL) { 969 //delete mIfrBinBuf; 970 mIfrBinBuf = NULL; 971 } 972 mLineNo = 0xFFFFFFFF; 973 mOffset = 0xFFFFFFFF; 974 mBinBufLen = 0; 975 mNext = NULL; 976 } 977 978 CIfrRecordInfoDB::CIfrRecordInfoDB ( 979 VOID 980 ) 981 { 982 mSwitch = TRUE; 983 mRecordCount = EFI_IFR_RECORDINFO_IDX_START; 984 mIfrRecordListHead = NULL; 985 mIfrRecordListTail = NULL; 986 } 987 988 CIfrRecordInfoDB::~CIfrRecordInfoDB ( 989 VOID 990 ) 991 { 992 SIfrRecord *pNode; 993 994 while (mIfrRecordListHead != NULL) { 995 pNode = mIfrRecordListHead; 996 mIfrRecordListHead = mIfrRecordListHead->mNext; 997 delete pNode; 998 } 999 } 1000 1001 SIfrRecord * 1002 CIfrRecordInfoDB::GetRecordInfoFromIdx ( 1003 IN UINT32 RecordIdx 1004 ) 1005 { 1006 UINT32 Idx; 1007 SIfrRecord *pNode = NULL; 1008 1009 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) { 1010 return NULL; 1011 } 1012 1013 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead; 1014 (Idx != RecordIdx) && (pNode != NULL); 1015 Idx++, pNode = pNode->mNext) 1016 ; 1017 1018 return pNode; 1019 } 1020 1021 UINT32 1022 CIfrRecordInfoDB::IfrRecordRegister ( 1023 IN UINT32 LineNo, 1024 IN CHAR8 *IfrBinBuf, 1025 IN UINT8 BinBufLen, 1026 IN UINT32 Offset 1027 ) 1028 { 1029 SIfrRecord *pNew; 1030 1031 if (mSwitch == FALSE) { 1032 return EFI_IFR_RECORDINFO_IDX_INVALUD; 1033 } 1034 1035 if ((pNew = new SIfrRecord) == NULL) { 1036 return EFI_IFR_RECORDINFO_IDX_INVALUD; 1037 } 1038 1039 if (mIfrRecordListHead == NULL) { 1040 mIfrRecordListHead = pNew; 1041 mIfrRecordListTail = pNew; 1042 } else { 1043 mIfrRecordListTail->mNext = pNew; 1044 mIfrRecordListTail = pNew; 1045 } 1046 mRecordCount++; 1047 1048 return mRecordCount; 1049 } 1050 1051 VOID 1052 CIfrRecordInfoDB::IfrRecordInfoUpdate ( 1053 IN UINT32 RecordIdx, 1054 IN UINT32 LineNo, 1055 IN CHAR8 *BinBuf, 1056 IN UINT8 BinBufLen, 1057 IN UINT32 Offset 1058 ) 1059 { 1060 SIfrRecord *pNode; 1061 SIfrRecord *Prev; 1062 1063 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) { 1064 return; 1065 } 1066 1067 if (LineNo == 0) { 1068 // 1069 // Line number is not specified explicitly, try to use line number of previous opcode 1070 // 1071 Prev = GetRecordInfoFromIdx (RecordIdx - 1); 1072 if (Prev != NULL) { 1073 LineNo = Prev->mLineNo; 1074 } 1075 } 1076 1077 pNode->mLineNo = LineNo; 1078 pNode->mOffset = Offset; 1079 pNode->mBinBufLen = BinBufLen; 1080 pNode->mIfrBinBuf = BinBuf; 1081 1082 } 1083 1084 VOID 1085 CIfrRecordInfoDB::IfrRecordOutput ( 1086 OUT PACKAGE_DATA &TBuffer 1087 ) 1088 { 1089 CHAR8 *Temp; 1090 SIfrRecord *pNode; 1091 1092 if (TBuffer.Buffer != NULL) { 1093 delete TBuffer.Buffer; 1094 } 1095 1096 TBuffer.Size = 0; 1097 TBuffer.Buffer = NULL; 1098 1099 1100 if (mSwitch == FALSE) { 1101 return; 1102 } 1103 1104 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 1105 TBuffer.Size += pNode->mBinBufLen; 1106 } 1107 1108 if (TBuffer.Size != 0) { 1109 TBuffer.Buffer = new CHAR8[TBuffer.Size]; 1110 } else { 1111 return; 1112 } 1113 1114 Temp = TBuffer.Buffer; 1115 1116 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 1117 if (pNode->mIfrBinBuf != NULL) { 1118 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen); 1119 Temp += pNode->mBinBufLen; 1120 } 1121 } 1122 1123 return; 1124 } 1125 1126 VOID 1127 CIfrRecordInfoDB::IfrRecordOutput ( 1128 IN FILE *File, 1129 IN UINT32 LineNo 1130 ) 1131 { 1132 SIfrRecord *pNode; 1133 UINT8 Index; 1134 UINT32 TotalSize; 1135 1136 if (mSwitch == FALSE) { 1137 return; 1138 } 1139 1140 if (File == NULL) { 1141 return; 1142 } 1143 1144 TotalSize = 0; 1145 1146 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 1147 if (pNode->mLineNo == LineNo || LineNo == 0) { 1148 fprintf (File, ">%08X: ", pNode->mOffset); 1149 TotalSize += pNode->mBinBufLen; 1150 if (pNode->mIfrBinBuf != NULL) { 1151 for (Index = 0; Index < pNode->mBinBufLen; Index++) { 1152 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index])); 1153 } 1154 } 1155 fprintf (File, "\n"); 1156 } 1157 } 1158 1159 if (LineNo == 0) { 1160 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize); 1161 } 1162 } 1163 1164 // 1165 // for framework vfr file 1166 // adjust opcode sequence for uefi IFR format 1167 // adjust inconsistent and varstore into the right position. 1168 // 1169 BOOLEAN 1170 CIfrRecordInfoDB::CheckQuestionOpCode ( 1171 IN UINT8 OpCode 1172 ) 1173 { 1174 switch (OpCode) { 1175 case EFI_IFR_CHECKBOX_OP: 1176 case EFI_IFR_NUMERIC_OP: 1177 case EFI_IFR_PASSWORD_OP: 1178 case EFI_IFR_ONE_OF_OP: 1179 case EFI_IFR_ACTION_OP: 1180 case EFI_IFR_STRING_OP: 1181 case EFI_IFR_DATE_OP: 1182 case EFI_IFR_TIME_OP: 1183 case EFI_IFR_ORDERED_LIST_OP: 1184 return TRUE; 1185 default: 1186 return FALSE; 1187 } 1188 } 1189 1190 BOOLEAN 1191 CIfrRecordInfoDB::CheckIdOpCode ( 1192 IN UINT8 OpCode 1193 ) 1194 { 1195 switch (OpCode) { 1196 case EFI_IFR_EQ_ID_VAL_OP: 1197 case EFI_IFR_EQ_ID_ID_OP: 1198 case EFI_IFR_EQ_ID_VAL_LIST_OP: 1199 case EFI_IFR_QUESTION_REF1_OP: 1200 return TRUE; 1201 default: 1202 return FALSE; 1203 } 1204 } 1205 1206 EFI_QUESTION_ID 1207 CIfrRecordInfoDB::GetOpcodeQuestionId ( 1208 IN EFI_IFR_OP_HEADER *OpHead 1209 ) 1210 { 1211 EFI_IFR_QUESTION_HEADER *QuestionHead; 1212 1213 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1); 1214 1215 return QuestionHead->QuestionId; 1216 } 1217 1218 SIfrRecord * 1219 CIfrRecordInfoDB::GetRecordInfoFromOffset ( 1220 IN UINT32 Offset 1221 ) 1222 { 1223 SIfrRecord *pNode = NULL; 1224 1225 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 1226 if (pNode->mOffset == Offset) { 1227 return pNode; 1228 } 1229 } 1230 1231 return pNode; 1232 } 1233 1234 /* 1235 Add just the op code position. 1236 1237 From 1238 1239 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode | 1240 1241 To 1242 1243 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode | 1244 1245 */ 1246 BOOLEAN 1247 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords ( 1248 VOID 1249 ) 1250 { 1251 UINT32 OpcodeOffset; 1252 SIfrRecord *pNode, *pPreNode; 1253 SIfrRecord *pStartNode, *pNodeBeforeStart; 1254 SIfrRecord *pEndNode; 1255 1256 pStartNode = NULL; 1257 pEndNode = NULL; 1258 OpcodeOffset = 0; 1259 1260 // 1261 // Base on the offset info to get the node. 1262 // 1263 for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) { 1264 if (OpcodeOffset == gAdjustOpcodeOffset) { 1265 pStartNode = pNode; 1266 pNodeBeforeStart = pPreNode; 1267 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) { 1268 pEndNode = pPreNode; 1269 } 1270 1271 OpcodeOffset += pNode->mBinBufLen; 1272 } 1273 1274 // 1275 // Check the value. 1276 // 1277 if (pEndNode == NULL || pStartNode == NULL) { 1278 return FALSE; 1279 } 1280 1281 // 1282 // Adjust the node. pPreNode save the Node before mIfrRecordListTail 1283 // 1284 pNodeBeforeStart->mNext = pEndNode->mNext; 1285 pPreNode->mNext = pStartNode; 1286 pEndNode->mNext = mIfrRecordListTail; 1287 1288 return TRUE; 1289 } 1290 1291 VOID 1292 CIfrRecordInfoDB::IfrAdjustOffsetForRecord ( 1293 VOID 1294 ) 1295 { 1296 UINT32 OpcodeOffset; 1297 SIfrRecord *pNode; 1298 1299 OpcodeOffset = 0; 1300 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 1301 pNode->mOffset = OpcodeOffset; 1302 OpcodeOffset += pNode->mBinBufLen; 1303 } 1304 } 1305 1306 EFI_VFR_RETURN_CODE 1307 CIfrRecordInfoDB::IfrRecordAdjust ( 1308 VOID 1309 ) 1310 { 1311 SIfrRecord *pNode, *preNode; 1312 SIfrRecord *uNode, *tNode; 1313 EFI_IFR_OP_HEADER *OpHead, *tOpHead; 1314 EFI_QUESTION_ID QuestionId; 1315 UINT32 StackCount; 1316 UINT32 QuestionScope; 1317 UINT32 OpcodeOffset; 1318 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, }; 1319 EFI_VFR_RETURN_CODE Status; 1320 1321 // 1322 // Init local variable 1323 // 1324 Status = VFR_RETURN_SUCCESS; 1325 pNode = mIfrRecordListHead; 1326 preNode = pNode; 1327 QuestionScope = 0; 1328 while (pNode != NULL) { 1329 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf; 1330 1331 // 1332 // make sure the inconsistent opcode in question scope 1333 // 1334 if (QuestionScope > 0) { 1335 QuestionScope += OpHead->Scope; 1336 if (OpHead->OpCode == EFI_IFR_END_OP) { 1337 QuestionScope --; 1338 } 1339 } 1340 1341 if (CheckQuestionOpCode (OpHead->OpCode)) { 1342 QuestionScope = 1; 1343 } 1344 // 1345 // for the inconsistent opcode not in question scope, adjust it 1346 // 1347 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) { 1348 // 1349 // for inconsistent opcode not in question scope 1350 // 1351 1352 // 1353 // Count inconsistent opcode Scope 1354 // 1355 StackCount = OpHead->Scope; 1356 QuestionId = EFI_QUESTION_ID_INVALID; 1357 tNode = pNode; 1358 while (tNode != NULL && StackCount > 0) { 1359 tNode = tNode->mNext; 1360 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf; 1361 // 1362 // Calculate Scope Number 1363 // 1364 StackCount += tOpHead->Scope; 1365 if (tOpHead->OpCode == EFI_IFR_END_OP) { 1366 StackCount --; 1367 } 1368 // 1369 // by IdEqual opcode to get QuestionId 1370 // 1371 if (QuestionId == EFI_QUESTION_ID_INVALID && 1372 CheckIdOpCode (tOpHead->OpCode)) { 1373 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1); 1374 } 1375 } 1376 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) { 1377 // 1378 // report error; not found 1379 // 1380 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId); 1381 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg); 1382 Status = VFR_RETURN_MISMATCHED; 1383 break; 1384 } 1385 // 1386 // extract inconsistent opcode list 1387 // pNode is Incosistent opcode, tNode is End Opcode 1388 // 1389 1390 // 1391 // insert inconsistent opcode list into the right question scope by questionid 1392 // 1393 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) { 1394 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf; 1395 if (CheckQuestionOpCode (tOpHead->OpCode) && 1396 (QuestionId == GetOpcodeQuestionId (tOpHead))) { 1397 break; 1398 } 1399 } 1400 // 1401 // insert inconsistent opcode list and check LATE_CHECK flag 1402 // 1403 if (uNode != NULL) { 1404 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) { 1405 // 1406 // if LATE_CHECK flag is set, change inconsistent to nosumbit 1407 // 1408 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP; 1409 } 1410 1411 // 1412 // skip the default storage for Date and Time 1413 // 1414 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) { 1415 uNode = uNode->mNext; 1416 } 1417 1418 preNode->mNext = tNode->mNext; 1419 tNode->mNext = uNode->mNext; 1420 uNode->mNext = pNode; 1421 // 1422 // reset pNode to head list, scan the whole list again. 1423 // 1424 pNode = mIfrRecordListHead; 1425 preNode = pNode; 1426 QuestionScope = 0; 1427 continue; 1428 } else { 1429 // 1430 // not found matched question id, report error 1431 // 1432 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId); 1433 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg); 1434 Status = VFR_RETURN_MISMATCHED; 1435 break; 1436 } 1437 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || 1438 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) { 1439 // 1440 // for new added group of varstore opcode 1441 // 1442 tNode = pNode; 1443 while (tNode->mNext != NULL) { 1444 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf; 1445 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && 1446 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) { 1447 break; 1448 } 1449 tNode = tNode->mNext; 1450 } 1451 1452 if (tNode->mNext == NULL) { 1453 // 1454 // invalid IfrCode, IfrCode end by EndOpCode 1455 // 1456 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end"); 1457 Status = VFR_RETURN_MISMATCHED; 1458 break; 1459 } 1460 1461 if (tOpHead->OpCode != EFI_IFR_END_OP) { 1462 // 1463 // not new added varstore, which are not needed to be adjust. 1464 // 1465 preNode = tNode; 1466 pNode = tNode->mNext; 1467 continue; 1468 } else { 1469 // 1470 // move new added varstore opcode to the position befor form opcode 1471 // varstore opcode between pNode and tNode 1472 // 1473 1474 // 1475 // search form opcode from begin 1476 // 1477 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) { 1478 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf; 1479 if (tOpHead->OpCode == EFI_IFR_FORM_OP) { 1480 break; 1481 } 1482 } 1483 // 1484 // Insert varstore opcode beform form opcode if form opcode is found 1485 // 1486 if (uNode->mNext != NULL) { 1487 preNode->mNext = tNode->mNext; 1488 tNode->mNext = uNode->mNext; 1489 uNode->mNext = pNode; 1490 // 1491 // reset pNode to head list, scan the whole list again. 1492 // 1493 pNode = mIfrRecordListHead; 1494 preNode = pNode; 1495 QuestionScope = 0; 1496 continue; 1497 } else { 1498 // 1499 // not found form, continue scan IfrRecord list 1500 // 1501 preNode = tNode; 1502 pNode = tNode->mNext; 1503 continue; 1504 } 1505 } 1506 } 1507 // 1508 // next node 1509 // 1510 preNode = pNode; 1511 pNode = pNode->mNext; 1512 } 1513 1514 // 1515 // Update Ifr Opcode Offset 1516 // 1517 if (Status == VFR_RETURN_SUCCESS) { 1518 IfrAdjustOffsetForRecord (); 1519 } 1520 return Status; 1521 } 1522 1523 CIfrRecordInfoDB gCIfrRecordInfoDB; 1524 1525 VOID 1526 CIfrObj::_EMIT_PENDING_OBJ ( 1527 VOID 1528 ) 1529 { 1530 CHAR8 *ObjBinBuf = NULL; 1531 1532 // 1533 // do nothing 1534 // 1535 if (!mDelayEmit || !gCreateOp) { 1536 return; 1537 } 1538 1539 mPkgOffset = gCFormPkg.GetPkgLength (); 1540 // 1541 // update data buffer to package data 1542 // 1543 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen); 1544 if (ObjBinBuf != NULL) { 1545 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen); 1546 } 1547 1548 // 1549 // update bin buffer to package data buffer 1550 // 1551 if (mObjBinBuf != NULL) { 1552 delete mObjBinBuf; 1553 mObjBinBuf = ObjBinBuf; 1554 } 1555 1556 mDelayEmit = FALSE; 1557 } 1558 1559 /* 1560 * The definition of CIfrObj's member function 1561 */ 1562 static struct { 1563 UINT8 mSize; 1564 UINT8 mScope; 1565 } gOpcodeSizesScopeTable[] = { 1566 { 0, 0 }, // EFI_IFR_INVALID - 0x00 1567 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP 1568 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP 1569 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP 1570 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP 1571 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05 1572 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP 1573 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP 1574 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP 1575 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP 1576 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A 1577 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP 1578 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP 1579 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP 1580 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE 1581 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP 1582 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10 1583 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP 1584 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP 1585 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP 1586 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14 1587 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP 1588 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP 1589 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP 1590 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP 1591 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19 1592 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP 1593 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP 1594 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP 1595 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP 1596 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E 1597 { 0, 0 }, // 0x1F 1598 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20 1599 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21 1600 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22 1601 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23 1602 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP 1603 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP 1604 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP 1605 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP 1606 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28 1607 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP 1608 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A 1609 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B 1610 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C 1611 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D 1612 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E 1613 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F 1614 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP 1615 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP 1616 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP 1617 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP 1618 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34 1619 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP 1620 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP 1621 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP 1622 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP 1623 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP 1624 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A 1625 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP 1626 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP 1627 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP 1628 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E 1629 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP 1630 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP 1631 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41 1632 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8 1633 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16 1634 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32 1635 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64 1636 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46 1637 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP 1638 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP 1639 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP 1640 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP 1641 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP 1642 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP 1643 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP 1644 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E 1645 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP 1646 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP 1647 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP 1648 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP 1649 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP 1650 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP 1651 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP 1652 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP 1653 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57 1654 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP 1655 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP 1656 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP 1657 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP 1658 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C 1659 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D 1660 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP 1661 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP 1662 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60 1663 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61 1664 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62 1665 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63 1666 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64 1667 }; 1668 1669 #ifdef CIFROBJ_DEUBG 1670 static struct { 1671 CHAR8 *mIfrName; 1672 } gIfrObjPrintDebugTable[] = { 1673 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF", 1674 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED", 1675 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF", 1676 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT", 1677 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH", 1678 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST", 1679 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END", 1680 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL", 1681 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND", 1682 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT", 1683 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2", 1684 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE", 1685 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN", 1686 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE", 1687 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN", 1688 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID", 1689 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2", 1690 }; 1691 1692 VOID 1693 CIFROBJ_DEBUG_PRINT ( 1694 IN UINT8 OpCode 1695 ) 1696 { 1697 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName); 1698 } 1699 #else 1700 1701 #define CIFROBJ_DEBUG_PRINT(OpCode) 1702 1703 #endif 1704 1705 BOOLEAN gCreateOp = TRUE; 1706 1707 CIfrObj::CIfrObj ( 1708 IN UINT8 OpCode, 1709 OUT CHAR8 **IfrObj, 1710 IN UINT8 ObjBinLen, 1711 IN BOOLEAN DelayEmit 1712 ) 1713 { 1714 mDelayEmit = DelayEmit; 1715 mPkgOffset = gCFormPkg.GetPkgLength (); 1716 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen; 1717 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH]; 1718 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD; 1719 1720 if (IfrObj != NULL) { 1721 *IfrObj = mObjBinBuf; 1722 } 1723 1724 CIFROBJ_DEBUG_PRINT (OpCode); 1725 } 1726 1727 CIfrObj::~CIfrObj ( 1728 VOID 1729 ) 1730 { 1731 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) { 1732 _EMIT_PENDING_OBJ (); 1733 } 1734 1735 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset); 1736 } 1737 1738 /* 1739 * The definition of CIfrObj's member function 1740 */ 1741 UINT8 gScopeCount = 0; 1742 1743 CIfrOpHeader::CIfrOpHeader ( 1744 IN UINT8 OpCode, 1745 IN VOID *StartAddr, 1746 IN UINT8 Length 1747 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr) 1748 { 1749 mHeader->OpCode = OpCode; 1750 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length; 1751 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0; 1752 } 1753 1754 CIfrOpHeader::CIfrOpHeader ( 1755 IN CIfrOpHeader &OpHdr 1756 ) 1757 { 1758 mHeader = OpHdr.mHeader; 1759 } 1760 1761 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, }; 1762