1 /** @file 2 3 Vfr common library functions. 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 "stdlib.h" 18 #include "CommonLib.h" 19 #include "VfrUtilityLib.h" 20 #include "VfrFormPkg.h" 21 22 VOID 23 CVfrBinaryOutput::WriteLine ( 24 IN FILE *pFile, 25 IN UINT32 LineBytes, 26 IN CONST CHAR8 *LineHeader, 27 IN CHAR8 *BlkBuf, 28 IN UINT32 BlkSize 29 ) 30 { 31 UINT32 Index; 32 33 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 34 return; 35 } 36 37 for (Index = 0; Index < BlkSize; Index++) { 38 if ((Index % LineBytes) == 0) { 39 fprintf (pFile, "\n%s", LineHeader); 40 } 41 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 42 } 43 } 44 45 VOID 46 CVfrBinaryOutput::WriteEnd ( 47 IN FILE *pFile, 48 IN UINT32 LineBytes, 49 IN CONST CHAR8 *LineHeader, 50 IN CHAR8 *BlkBuf, 51 IN UINT32 BlkSize 52 ) 53 { 54 UINT32 Index; 55 56 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 57 return; 58 } 59 60 for (Index = 0; Index < BlkSize - 1; Index++) { 61 if ((Index % LineBytes) == 0) { 62 fprintf (pFile, "\n%s", LineHeader); 63 } 64 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 65 } 66 67 if ((Index % LineBytes) == 0) { 68 fprintf (pFile, "\n%s", LineHeader); 69 } 70 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); 71 } 72 73 SConfigInfo::SConfigInfo ( 74 IN UINT8 Type, 75 IN UINT16 Offset, 76 IN UINT32 Width, 77 IN EFI_IFR_TYPE_VALUE Value 78 ) 79 { 80 mNext = NULL; 81 mOffset = Offset; 82 mWidth = (UINT16)Width; 83 mValue = new UINT8[mWidth]; 84 if (mValue == NULL) { 85 return; 86 } 87 88 switch (Type) { 89 case EFI_IFR_TYPE_NUM_SIZE_8 : 90 memcpy (mValue, &Value.u8, mWidth); 91 break; 92 case EFI_IFR_TYPE_NUM_SIZE_16 : 93 memcpy (mValue, &Value.u16, mWidth); 94 break; 95 case EFI_IFR_TYPE_NUM_SIZE_32 : 96 memcpy (mValue, &Value.u32, mWidth); 97 break; 98 case EFI_IFR_TYPE_NUM_SIZE_64 : 99 memcpy (mValue, &Value.u64, mWidth); 100 break; 101 case EFI_IFR_TYPE_BOOLEAN : 102 memcpy (mValue, &Value.b, mWidth); 103 break; 104 case EFI_IFR_TYPE_TIME : 105 memcpy (mValue, &Value.time, mWidth); 106 break; 107 case EFI_IFR_TYPE_DATE : 108 memcpy (mValue, &Value.date, mWidth); 109 break; 110 case EFI_IFR_TYPE_STRING : 111 memcpy (mValue, &Value.string, mWidth); 112 break; 113 case EFI_IFR_TYPE_BUFFER : 114 memcpy (mValue, &Value.u8, mWidth); 115 break; 116 117 case EFI_IFR_TYPE_OTHER : 118 return; 119 } 120 } 121 122 SConfigInfo::~SConfigInfo ( 123 VOID 124 ) 125 { 126 ARRAY_SAFE_FREE (mValue); 127 } 128 129 SConfigItem::SConfigItem ( 130 IN CHAR8 *Name, 131 IN EFI_GUID *Guid, 132 IN CHAR8 *Id 133 ) 134 { 135 mName = NULL; 136 mGuid = NULL; 137 mId = NULL; 138 mInfoStrList = NULL; 139 mNext = NULL; 140 141 if (Name != NULL) { 142 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) { 143 strcpy (mName, Name); 144 } 145 } 146 147 if (Guid != NULL) { 148 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) { 149 memcpy (mGuid, Guid, sizeof (EFI_GUID)); 150 } 151 } 152 153 if (Id != NULL) { 154 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) { 155 strcpy (mId, Id); 156 } 157 } 158 } 159 160 SConfigItem::SConfigItem ( 161 IN CHAR8 *Name, 162 IN EFI_GUID *Guid, 163 IN CHAR8 *Id, 164 IN UINT8 Type, 165 IN UINT16 Offset, 166 IN UINT16 Width, 167 IN EFI_IFR_TYPE_VALUE Value 168 ) 169 { 170 mName = NULL; 171 mGuid = NULL; 172 mId = NULL; 173 mInfoStrList = NULL; 174 mNext = NULL; 175 176 if (Name != NULL) { 177 if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) { 178 strcpy (mName, Name); 179 } 180 } 181 182 if (Guid != NULL) { 183 if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) { 184 memcpy (mGuid, Guid, sizeof (EFI_GUID)); 185 } 186 } 187 188 if (Id != NULL) { 189 if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) { 190 strcpy (mId, Id); 191 } 192 } 193 194 mInfoStrList = new SConfigInfo(Type, Offset, Width, Value); 195 } 196 197 SConfigItem::~SConfigItem ( 198 VOID 199 ) 200 { 201 SConfigInfo *Info; 202 203 ARRAY_SAFE_FREE (mName); 204 ARRAY_SAFE_FREE (mGuid); 205 ARRAY_SAFE_FREE (mId); 206 while (mInfoStrList != NULL) { 207 Info = mInfoStrList; 208 mInfoStrList = mInfoStrList->mNext; 209 210 BUFFER_SAFE_FREE (Info); 211 } 212 } 213 214 UINT8 215 CVfrBufferConfig::Register ( 216 IN CHAR8 *Name, 217 IN EFI_GUID *Guid, 218 IN CHAR8 *Id 219 ) 220 { 221 SConfigItem *pNew; 222 223 if (Select (Name, Guid) == 0) { 224 return 1; 225 } 226 227 if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) { 228 return 2; 229 } 230 231 if (mItemListHead == NULL) { 232 mItemListHead = pNew; 233 mItemListTail = pNew; 234 } else { 235 mItemListTail->mNext = pNew; 236 mItemListTail = pNew; 237 } 238 mItemListPos = pNew; 239 240 return 0; 241 } 242 243 VOID 244 CVfrBufferConfig::Open ( 245 VOID 246 ) 247 { 248 mItemListPos = mItemListHead; 249 } 250 251 BOOLEAN 252 CVfrBufferConfig::Eof( 253 VOID 254 ) 255 { 256 return (mItemListPos == NULL) ? TRUE : FALSE; 257 } 258 259 UINT8 260 CVfrBufferConfig::Select ( 261 IN CHAR8 *Name, 262 IN EFI_GUID *Guid, 263 IN CHAR8 *Id 264 ) 265 { 266 SConfigItem *p; 267 268 if (Name == NULL || Guid == NULL) { 269 mItemListPos = mItemListHead; 270 return 0; 271 } else { 272 for (p = mItemListHead; p != NULL; p = p->mNext) { 273 if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) { 274 continue; 275 } 276 277 if (Id != NULL) { 278 if (p->mId == NULL || strcmp (p->mId, Id) != 0) { 279 continue; 280 } 281 } else if (p->mId != NULL) { 282 continue; 283 } 284 285 mItemListPos = p; 286 return 0; 287 } 288 } 289 290 return 1; 291 } 292 293 UINT8 294 CVfrBufferConfig::Write ( 295 IN CONST CHAR8 Mode, 296 IN CHAR8 *Name, 297 IN EFI_GUID *Guid, 298 IN CHAR8 *Id, 299 IN UINT8 Type, 300 IN UINT16 Offset, 301 IN UINT32 Width, 302 IN EFI_IFR_TYPE_VALUE Value 303 ) 304 { 305 UINT8 Ret; 306 SConfigItem *pItem; 307 SConfigInfo *pInfo; 308 309 if ((Ret = Select (Name, Guid)) != 0) { 310 return Ret; 311 } 312 313 switch (Mode) { 314 case 'a' : // add 315 if (Select (Name, Guid, Id) != 0) { 316 if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) { 317 return 2; 318 } 319 if (mItemListHead == NULL) { 320 mItemListHead = pItem; 321 mItemListTail = pItem; 322 } else { 323 mItemListTail->mNext = pItem; 324 mItemListTail = pItem; 325 } 326 mItemListPos = pItem; 327 } else { 328 // tranverse the list to find out if there's already the value for the same offset 329 for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) { 330 if (pInfo->mOffset == Offset) { 331 return 0; 332 } 333 } 334 if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) { 335 return 2; 336 } 337 pInfo->mNext = mItemListPos->mInfoStrList; 338 mItemListPos->mInfoStrList = pInfo; 339 } 340 break; 341 342 case 'd' : // delete 343 if (mItemListHead == mItemListPos) { 344 mItemListHead = mItemListPos->mNext; 345 delete mItemListPos; 346 break; 347 } 348 349 for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext) 350 ; 351 352 pItem->mNext = mItemListPos->mNext; 353 if (mItemListTail == mItemListPos) { 354 mItemListTail = pItem; 355 } 356 delete mItemListPos; 357 mItemListPos = pItem->mNext; 358 break; 359 360 case 'i' : // set info 361 if (mItemListPos->mId != NULL) { 362 delete mItemListPos->mId; 363 } 364 mItemListPos->mId = NULL; 365 if (Id != NULL) { 366 if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) { 367 return 2; 368 } 369 strcpy (mItemListPos->mId, Id); 370 } 371 break; 372 373 default : 374 return 1; 375 } 376 377 return 0; 378 } 379 380 381 VOID 382 CVfrBufferConfig::Close ( 383 VOID 384 ) 385 { 386 mItemListPos = NULL; 387 } 388 389 #define BYTES_PRE_LINE 0x10 390 391 VOID 392 CVfrBufferConfig::OutputCFile ( 393 IN FILE *pFile, 394 IN CHAR8 *BaseName 395 ) 396 { 397 CVfrBinaryOutput Output; 398 SConfigItem *Item; 399 SConfigInfo *Info; 400 UINT32 TotalLen; 401 402 if (pFile == NULL) { 403 return; 404 } 405 406 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) { 407 if (Item->mId != NULL || Item->mInfoStrList == NULL) { 408 continue; 409 } 410 fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName); 411 412 TotalLen = sizeof (UINT32); 413 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { 414 TotalLen += sizeof (UINT16) * 2; 415 } 416 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32)); 417 418 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { 419 fprintf (pFile, "\n"); 420 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16)); 421 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16)); 422 } 423 fprintf (pFile, "\n};\n"); 424 } 425 426 for (Item = mItemListHead; Item != NULL; Item = Item->mNext) { 427 if (Item->mId != NULL && Item->mInfoStrList != NULL) { 428 fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId); 429 430 TotalLen = sizeof (UINT32); 431 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { 432 TotalLen += Info->mWidth + sizeof (UINT16) * 2; 433 } 434 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32)); 435 436 for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) { 437 fprintf (pFile, "\n"); 438 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16)); 439 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16)); 440 if (Info->mNext == NULL) { 441 Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth); 442 } else { 443 Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth); 444 } 445 } 446 fprintf (pFile, "\n};\n"); 447 } 448 } 449 } 450 451 CVfrBufferConfig::CVfrBufferConfig ( 452 VOID 453 ) 454 { 455 mItemListHead = NULL; 456 mItemListTail = NULL; 457 mItemListPos = NULL; 458 } 459 460 CVfrBufferConfig::~CVfrBufferConfig ( 461 VOID 462 ) 463 { 464 SConfigItem *p; 465 466 while (mItemListHead != NULL) { 467 p = mItemListHead; 468 mItemListHead = mItemListHead->mNext; 469 delete p; 470 } 471 472 mItemListHead = NULL; 473 mItemListTail = NULL; 474 mItemListPos = NULL; 475 } 476 477 CVfrBufferConfig gCVfrBufferConfig; 478 479 static struct { 480 CONST CHAR8 *mTypeName; 481 UINT8 mType; 482 UINT32 mSize; 483 UINT32 mAlign; 484 } gInternalTypesTable [] = { 485 {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)}, 486 {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)}, 487 {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)}, 488 {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)}, 489 {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)}, 490 {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)}, 491 {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)}, 492 {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)}, 493 {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)}, 494 {NULL, EFI_IFR_TYPE_OTHER, 0, 0} 495 }; 496 497 STATIC 498 BOOLEAN 499 _IS_INTERNAL_TYPE ( 500 IN CHAR8 *TypeName 501 ) 502 { 503 UINT32 Index; 504 505 if (TypeName == NULL) { 506 return FALSE; 507 } 508 509 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) { 510 if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) { 511 return TRUE; 512 } 513 } 514 515 return FALSE; 516 } 517 518 STATIC 519 CHAR8 * 520 TrimHex ( 521 IN CHAR8 *Str, 522 OUT bool *IsHex 523 ) 524 { 525 *IsHex = FALSE; 526 527 while (*Str && *Str == ' ') { 528 Str++; 529 } 530 while (*Str && *Str == '0') { 531 Str++; 532 } 533 if (*Str && (*Str == 'x' || *Str == 'X')) { 534 Str++; 535 *IsHex = TRUE; 536 } 537 538 return Str; 539 } 540 541 UINT32 542 _STR2U32 ( 543 IN CHAR8 *Str 544 ) 545 { 546 bool IsHex; 547 UINT32 Value; 548 CHAR8 c; 549 550 Str = TrimHex (Str, &IsHex); 551 for (Value = 0; (c = *Str) != '\0'; Str++) { 552 // 553 // BUG: does not handle overflow here 554 // 555 (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); 556 557 if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { 558 Value += (c - 'a' + 10); 559 } 560 if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) { 561 Value += (c - 'A' + 10); 562 } 563 if (c >= '0' && c <= '9') { 564 Value += (c - '0'); 565 } 566 } 567 568 return Value; 569 } 570 571 VOID 572 CVfrVarDataTypeDB::RegisterNewType ( 573 IN SVfrDataType *New 574 ) 575 { 576 New->mNext = mDataTypeList; 577 mDataTypeList = New; 578 } 579 580 EFI_VFR_RETURN_CODE 581 CVfrVarDataTypeDB::ExtractStructTypeName ( 582 IN CHAR8 *&VarStr, 583 OUT CHAR8 *TName 584 ) 585 { 586 if (TName == NULL) { 587 return VFR_RETURN_FATAL_ERROR; 588 } 589 590 while((*VarStr != '\0') && (*VarStr != '.')) { 591 *TName = *VarStr; 592 VarStr++; 593 TName++; 594 } 595 *TName = '\0'; 596 if (*VarStr == '.') { 597 VarStr++; 598 } 599 600 return VFR_RETURN_SUCCESS; 601 } 602 603 EFI_VFR_RETURN_CODE 604 CVfrVarDataTypeDB::ExtractFieldNameAndArrary ( 605 IN CHAR8 *&VarStr, 606 IN CHAR8 *FName, 607 OUT UINT32 &ArrayIdx 608 ) 609 { 610 UINT32 Idx; 611 CHAR8 ArrayStr[MAX_NAME_LEN + 1]; 612 613 ArrayIdx = INVALID_ARRAY_INDEX; 614 615 if (FName == NULL) { 616 return VFR_RETURN_FATAL_ERROR; 617 } 618 619 while((*VarStr != '\0') && 620 (*VarStr != '.') && 621 (*VarStr != '[') && 622 (*VarStr != ']')) { 623 *FName = *VarStr; 624 VarStr++; 625 FName++; 626 } 627 *FName = '\0'; 628 629 switch (*VarStr) { 630 case '.' : 631 VarStr++; 632 case '\0': 633 return VFR_RETURN_SUCCESS; 634 case '[' : 635 VarStr++; 636 for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) { 637 ArrayStr[Idx] = *VarStr; 638 } 639 ArrayStr[Idx] = '\0'; 640 641 if ((*VarStr != ']') && (ArrayStr[0] == '\0')) { 642 return VFR_RETURN_DATA_STRING_ERROR; 643 } 644 ArrayIdx = _STR2U32 (ArrayStr); 645 if (*VarStr == ']') { 646 VarStr++; 647 } 648 if (*VarStr == '.') { 649 VarStr++; 650 } 651 return VFR_RETURN_SUCCESS; 652 case ']': 653 return VFR_RETURN_DATA_STRING_ERROR; 654 } 655 656 return VFR_RETURN_SUCCESS; 657 } 658 659 EFI_VFR_RETURN_CODE 660 CVfrVarDataTypeDB::GetTypeField ( 661 IN CONST CHAR8 *FName, 662 IN SVfrDataType *Type, 663 OUT SVfrDataField *&Field 664 ) 665 { 666 SVfrDataField *pField = NULL; 667 668 if ((FName == NULL) || (Type == NULL)) { 669 return VFR_RETURN_FATAL_ERROR; 670 } 671 672 for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) { 673 // 674 // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote, 675 // add code to adjust it. 676 // 677 if (Type->mType == EFI_IFR_TYPE_TIME) { 678 if (strcmp (FName, "Hour") == 0) { 679 FName = "Hours"; 680 } else if (strcmp (FName, "Minute") == 0) { 681 FName = "Minuts"; 682 } else if (strcmp (FName, "Second") == 0) { 683 FName = "Seconds"; 684 } 685 } 686 687 if (strcmp (pField->mFieldName, FName) == 0) { 688 Field = pField; 689 return VFR_RETURN_SUCCESS; 690 } 691 } 692 693 return VFR_RETURN_UNDEFINED; 694 } 695 696 EFI_VFR_RETURN_CODE 697 CVfrVarDataTypeDB::GetFieldOffset ( 698 IN SVfrDataField *Field, 699 IN UINT32 ArrayIdx, 700 OUT UINT32 &Offset 701 ) 702 { 703 if (Field == NULL) { 704 return VFR_RETURN_FATAL_ERROR; 705 } 706 707 // 708 // Framework Vfr file Array Index is from 1. 709 // But Uefi Vfr file Array Index is from 0. 710 // 711 if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) { 712 if (ArrayIdx == 0) { 713 return VFR_RETURN_ERROR_ARRARY_NUM; 714 } 715 ArrayIdx = ArrayIdx - 1; 716 } 717 718 if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) { 719 return VFR_RETURN_ERROR_ARRARY_NUM; 720 } 721 722 // 723 // Be compatible with the current usage 724 // If ArraryIdx is not specified, the first one is used. 725 // 726 // if ArrayNum is larger than zero, ArraryIdx must be specified. 727 // 728 // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) { 729 // return VFR_RETURN_ERROR_ARRARY_NUM; 730 // } 731 // 732 733 Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx); 734 return VFR_RETURN_SUCCESS; 735 } 736 737 UINT8 738 CVfrVarDataTypeDB::GetFieldWidth ( 739 IN SVfrDataField *Field 740 ) 741 { 742 if (Field == NULL) { 743 return 0; 744 } 745 746 return Field->mFieldType->mType; 747 } 748 749 UINT32 750 CVfrVarDataTypeDB::GetFieldSize ( 751 IN SVfrDataField *Field, 752 IN UINT32 ArrayIdx 753 ) 754 { 755 if (Field == NULL) { 756 return VFR_RETURN_FATAL_ERROR; 757 } 758 759 if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) { 760 return Field->mFieldType->mTotalSize * Field->mArrayNum; 761 } else { 762 return Field->mFieldType->mTotalSize; 763 } 764 } 765 766 VOID 767 CVfrVarDataTypeDB::InternalTypesListInit ( 768 VOID 769 ) 770 { 771 SVfrDataType *New = NULL; 772 UINT32 Index; 773 774 for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) { 775 New = new SVfrDataType; 776 if (New != NULL) { 777 strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName); 778 New->mType = gInternalTypesTable[Index].mType; 779 New->mAlign = gInternalTypesTable[Index].mAlign; 780 New->mTotalSize = gInternalTypesTable[Index].mSize; 781 if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) { 782 SVfrDataField *pYearField = new SVfrDataField; 783 SVfrDataField *pMonthField = new SVfrDataField; 784 SVfrDataField *pDayField = new SVfrDataField; 785 786 strcpy (pYearField->mFieldName, "Year"); 787 GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType); 788 pYearField->mOffset = 0; 789 pYearField->mNext = pMonthField; 790 pYearField->mArrayNum = 0; 791 792 strcpy (pMonthField->mFieldName, "Month"); 793 GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType); 794 pMonthField->mOffset = 2; 795 pMonthField->mNext = pDayField; 796 pMonthField->mArrayNum = 0; 797 798 strcpy (pDayField->mFieldName, "Day"); 799 GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType); 800 pDayField->mOffset = 3; 801 pDayField->mNext = NULL; 802 pDayField->mArrayNum = 0; 803 804 New->mMembers = pYearField; 805 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) { 806 SVfrDataField *pHoursField = new SVfrDataField; 807 SVfrDataField *pMinutesField = new SVfrDataField; 808 SVfrDataField *pSecondsField = new SVfrDataField; 809 810 strcpy (pHoursField->mFieldName, "Hours"); 811 GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType); 812 pHoursField->mOffset = 0; 813 pHoursField->mNext = pMinutesField; 814 pHoursField->mArrayNum = 0; 815 816 strcpy (pMinutesField->mFieldName, "Minutes"); 817 GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType); 818 pMinutesField->mOffset = 1; 819 pMinutesField->mNext = pSecondsField; 820 pMinutesField->mArrayNum = 0; 821 822 strcpy (pSecondsField->mFieldName, "Seconds"); 823 GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType); 824 pSecondsField->mOffset = 2; 825 pSecondsField->mNext = NULL; 826 pSecondsField->mArrayNum = 0; 827 828 New->mMembers = pHoursField; 829 } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) { 830 SVfrDataField *pQuestionIdField = new SVfrDataField; 831 SVfrDataField *pFormIdField = new SVfrDataField; 832 SVfrDataField *pFormSetGuidField = new SVfrDataField; 833 SVfrDataField *pDevicePathField = new SVfrDataField; 834 835 strcpy (pQuestionIdField->mFieldName, "QuestionId"); 836 GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType); 837 pQuestionIdField->mOffset = 0; 838 pQuestionIdField->mNext = pFormIdField; 839 pQuestionIdField->mArrayNum = 0; 840 841 strcpy (pFormIdField->mFieldName, "FormId"); 842 GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType); 843 pFormIdField->mOffset = 2; 844 pFormIdField->mNext = pFormSetGuidField; 845 pFormIdField->mArrayNum = 0; 846 847 strcpy (pFormSetGuidField->mFieldName, "FormSetGuid"); 848 GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType); 849 pFormSetGuidField->mOffset = 4; 850 pFormSetGuidField->mNext = pDevicePathField; 851 pFormSetGuidField->mArrayNum = 0; 852 853 strcpy (pDevicePathField->mFieldName, "DevicePath"); 854 GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType); 855 pDevicePathField->mOffset = 20; 856 pDevicePathField->mNext = NULL; 857 pDevicePathField->mArrayNum = 0; 858 859 New->mMembers = pQuestionIdField; 860 } else { 861 New->mMembers = NULL; 862 } 863 New->mNext = NULL; 864 RegisterNewType (New); 865 New = NULL; 866 } 867 } 868 } 869 870 CVfrVarDataTypeDB::CVfrVarDataTypeDB ( 871 VOID 872 ) 873 { 874 mDataTypeList = NULL; 875 mNewDataType = NULL; 876 mCurrDataField = NULL; 877 mPackAlign = DEFAULT_PACK_ALIGN; 878 mPackStack = NULL; 879 mFirstNewDataTypeName = NULL; 880 881 InternalTypesListInit (); 882 } 883 884 CVfrVarDataTypeDB::~CVfrVarDataTypeDB ( 885 VOID 886 ) 887 { 888 SVfrDataType *pType; 889 SVfrDataField *pField; 890 SVfrPackStackNode *pPack; 891 892 if (mNewDataType != NULL) { 893 delete mNewDataType; 894 } 895 896 while (mDataTypeList != NULL) { 897 pType = mDataTypeList; 898 mDataTypeList = mDataTypeList->mNext; 899 while(pType->mMembers != NULL) { 900 pField = pType->mMembers; 901 pType->mMembers = pType->mMembers->mNext; 902 delete pField; 903 } 904 delete pType; 905 } 906 907 while (mPackStack != NULL) { 908 pPack = mPackStack; 909 mPackStack = mPackStack->mNext; 910 delete pPack; 911 } 912 } 913 914 EFI_VFR_RETURN_CODE 915 CVfrVarDataTypeDB::Pack ( 916 IN UINT32 LineNum, 917 IN UINT8 Action, 918 IN CHAR8 *Identifier, 919 IN UINT32 Number 920 ) 921 { 922 UINT32 PackAlign; 923 CHAR8 Msg[MAX_STRING_LEN] = {0, }; 924 925 if (Action & VFR_PACK_SHOW) { 926 sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign); 927 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg); 928 } 929 930 if (Action & VFR_PACK_PUSH) { 931 SVfrPackStackNode *pNew = NULL; 932 933 if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) { 934 return VFR_RETURN_FATAL_ERROR; 935 } 936 pNew->mNext = mPackStack; 937 mPackStack = pNew; 938 } 939 940 if (Action & VFR_PACK_POP) { 941 SVfrPackStackNode *pNode = NULL; 942 943 if (mPackStack == NULL) { 944 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes"); 945 } 946 947 for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) { 948 if (pNode->Match (Identifier) == TRUE) { 949 mPackAlign = pNode->mNumber; 950 mPackStack = pNode->mNext; 951 } 952 } 953 } 954 955 if (Action & VFR_PACK_ASSIGN) { 956 PackAlign = (Number > 1) ? Number + Number % 2 : Number; 957 if ((PackAlign == 0) || (PackAlign > 16)) { 958 gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'"); 959 } else { 960 mPackAlign = PackAlign; 961 } 962 } 963 964 return VFR_RETURN_SUCCESS; 965 } 966 967 VOID 968 CVfrVarDataTypeDB::DeclareDataTypeBegin ( 969 VOID 970 ) 971 { 972 SVfrDataType *pNewType = NULL; 973 974 pNewType = new SVfrDataType; 975 pNewType->mTypeName[0] = '\0'; 976 pNewType->mType = EFI_IFR_TYPE_OTHER; 977 pNewType->mAlign = DEFAULT_ALIGN; 978 pNewType->mTotalSize = 0; 979 pNewType->mMembers = NULL; 980 pNewType->mNext = NULL; 981 982 mNewDataType = pNewType; 983 } 984 985 EFI_VFR_RETURN_CODE 986 CVfrVarDataTypeDB::SetNewTypeName ( 987 IN CHAR8 *TypeName 988 ) 989 { 990 SVfrDataType *pType; 991 992 if (mNewDataType == NULL) { 993 return VFR_RETURN_ERROR_SKIPED; 994 } 995 if (TypeName == NULL) { 996 return VFR_RETURN_FATAL_ERROR; 997 } 998 if (strlen(TypeName) >= MAX_NAME_LEN) { 999 return VFR_RETURN_INVALID_PARAMETER; 1000 } 1001 1002 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { 1003 if (strcmp(pType->mTypeName, TypeName) == 0) { 1004 return VFR_RETURN_REDEFINED; 1005 } 1006 } 1007 1008 strcpy(mNewDataType->mTypeName, TypeName); 1009 return VFR_RETURN_SUCCESS; 1010 } 1011 1012 EFI_VFR_RETURN_CODE 1013 CVfrVarDataTypeDB::DataTypeAddField ( 1014 IN CHAR8 *FieldName, 1015 IN CHAR8 *TypeName, 1016 IN UINT32 ArrayNum 1017 ) 1018 { 1019 SVfrDataField *pNewField = NULL; 1020 SVfrDataType *pFieldType = NULL; 1021 SVfrDataField *pTmp; 1022 UINT32 Align; 1023 1024 CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS); 1025 1026 if (strlen (FieldName) >= MAX_NAME_LEN) { 1027 return VFR_RETURN_INVALID_PARAMETER; 1028 } 1029 1030 for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) { 1031 if (strcmp (pTmp->mFieldName, FieldName) == 0) { 1032 return VFR_RETURN_REDEFINED; 1033 } 1034 } 1035 1036 Align = MIN (mPackAlign, pFieldType->mAlign); 1037 1038 if ((pNewField = new SVfrDataField) == NULL) { 1039 return VFR_RETURN_OUT_FOR_RESOURCES; 1040 } 1041 strcpy (pNewField->mFieldName, FieldName); 1042 pNewField->mFieldType = pFieldType; 1043 pNewField->mArrayNum = ArrayNum; 1044 if ((mNewDataType->mTotalSize % Align) == 0) { 1045 pNewField->mOffset = mNewDataType->mTotalSize; 1046 } else { 1047 pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align); 1048 } 1049 if (mNewDataType->mMembers == NULL) { 1050 mNewDataType->mMembers = pNewField; 1051 pNewField->mNext = NULL; 1052 } else { 1053 for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext) 1054 ; 1055 pTmp->mNext = pNewField; 1056 pNewField->mNext = NULL; 1057 } 1058 1059 mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign)); 1060 mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum); 1061 1062 return VFR_RETURN_SUCCESS; 1063 } 1064 1065 VOID 1066 CVfrVarDataTypeDB::DeclareDataTypeEnd ( 1067 VOID 1068 ) 1069 { 1070 if (mNewDataType->mTypeName[0] == '\0') { 1071 return; 1072 } 1073 1074 if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) { 1075 mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign); 1076 } 1077 1078 RegisterNewType (mNewDataType); 1079 if (mFirstNewDataTypeName == NULL) { 1080 mFirstNewDataTypeName = mNewDataType->mTypeName; 1081 } 1082 1083 mNewDataType = NULL; 1084 } 1085 1086 EFI_VFR_RETURN_CODE 1087 CVfrVarDataTypeDB::GetDataType ( 1088 IN CHAR8 *TypeName, 1089 OUT SVfrDataType **DataType 1090 ) 1091 { 1092 SVfrDataType *pDataType = NULL; 1093 1094 if (TypeName == NULL) { 1095 return VFR_RETURN_ERROR_SKIPED; 1096 } 1097 1098 if (DataType == NULL) { 1099 return VFR_RETURN_FATAL_ERROR; 1100 } 1101 1102 *DataType = NULL; 1103 1104 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) { 1105 if (strcmp (TypeName, pDataType->mTypeName) == 0) { 1106 *DataType = pDataType; 1107 return VFR_RETURN_SUCCESS; 1108 } 1109 } 1110 1111 return VFR_RETURN_UNDEFINED; 1112 } 1113 1114 EFI_VFR_RETURN_CODE 1115 CVfrVarDataTypeDB::GetDataTypeSize ( 1116 IN UINT8 DataType, 1117 OUT UINT32 *Size 1118 ) 1119 { 1120 SVfrDataType *pDataType = NULL; 1121 1122 if (Size == NULL) { 1123 return VFR_RETURN_FATAL_ERROR; 1124 } 1125 1126 *Size = 0; 1127 DataType = DataType & 0x0F; 1128 1129 // 1130 // For user defined data type, the size can't be got by this function. 1131 // 1132 if (DataType == EFI_IFR_TYPE_OTHER) { 1133 return VFR_RETURN_SUCCESS; 1134 } 1135 1136 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) { 1137 if (DataType == pDataType->mType) { 1138 *Size = pDataType->mTotalSize; 1139 return VFR_RETURN_SUCCESS; 1140 } 1141 } 1142 1143 return VFR_RETURN_UNDEFINED; 1144 } 1145 1146 EFI_VFR_RETURN_CODE 1147 CVfrVarDataTypeDB::GetDataTypeSize ( 1148 IN CHAR8 *TypeName, 1149 OUT UINT32 *Size 1150 ) 1151 { 1152 SVfrDataType *pDataType = NULL; 1153 1154 if (Size == NULL) { 1155 return VFR_RETURN_FATAL_ERROR; 1156 } 1157 1158 *Size = 0; 1159 1160 for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) { 1161 if (strcmp (TypeName, pDataType->mTypeName) == 0) { 1162 *Size = pDataType->mTotalSize; 1163 return VFR_RETURN_SUCCESS; 1164 } 1165 } 1166 1167 return VFR_RETURN_UNDEFINED; 1168 } 1169 1170 EFI_VFR_RETURN_CODE 1171 CVfrVarDataTypeDB::GetDataFieldInfo ( 1172 IN CHAR8 *VarStr, 1173 OUT UINT16 &Offset, 1174 OUT UINT8 &Type, 1175 OUT UINT32 &Size 1176 ) 1177 { 1178 CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN]; 1179 UINT32 ArrayIdx, Tmp; 1180 SVfrDataType *pType = NULL; 1181 SVfrDataField *pField = NULL; 1182 1183 Offset = 0; 1184 Type = EFI_IFR_TYPE_OTHER; 1185 Size = 0; 1186 1187 CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS); 1188 CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS); 1189 1190 // 1191 // if it is not struct data type 1192 // 1193 Type = pType->mType; 1194 Size = pType->mTotalSize; 1195 1196 while (*VarStr != '\0') { 1197 CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS); 1198 CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS); 1199 pType = pField->mFieldType; 1200 CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS); 1201 Offset = (UINT16) (Offset + Tmp); 1202 Type = GetFieldWidth (pField); 1203 Size = GetFieldSize (pField, ArrayIdx); 1204 } 1205 return VFR_RETURN_SUCCESS; 1206 } 1207 1208 EFI_VFR_RETURN_CODE 1209 CVfrVarDataTypeDB::GetUserDefinedTypeNameList ( 1210 OUT CHAR8 ***NameList, 1211 OUT UINT32 *ListSize 1212 ) 1213 { 1214 UINT32 Index; 1215 SVfrDataType *pType; 1216 1217 if ((NameList == NULL) || (ListSize == NULL)) { 1218 return VFR_RETURN_FATAL_ERROR; 1219 } 1220 1221 *NameList = NULL; 1222 *ListSize = 0; 1223 1224 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { 1225 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) { 1226 (*ListSize)++; 1227 } 1228 } 1229 1230 if (*ListSize == 0) { 1231 return VFR_RETURN_SUCCESS; 1232 } 1233 1234 if ((*NameList = new CHAR8*[*ListSize]) == NULL) { 1235 *ListSize = 0; 1236 return VFR_RETURN_OUT_FOR_RESOURCES; 1237 } 1238 1239 for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) { 1240 if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) { 1241 (*NameList)[Index] = pType->mTypeName; 1242 } 1243 } 1244 return VFR_RETURN_SUCCESS; 1245 } 1246 1247 BOOLEAN 1248 CVfrVarDataTypeDB::IsTypeNameDefined ( 1249 IN CHAR8 *TypeName 1250 ) 1251 { 1252 SVfrDataType *pType; 1253 1254 if (TypeName == NULL) { 1255 return FALSE; 1256 } 1257 1258 for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) { 1259 if (strcmp (pType->mTypeName, TypeName) == 0) { 1260 return TRUE; 1261 } 1262 } 1263 1264 return FALSE; 1265 } 1266 1267 VOID 1268 CVfrVarDataTypeDB::Dump ( 1269 IN FILE *File 1270 ) 1271 { 1272 SVfrDataType *pTNode; 1273 SVfrDataField *pFNode; 1274 1275 fprintf (File, "\n\n***************************************************************\n"); 1276 fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign); 1277 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) { 1278 fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize); 1279 fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName); 1280 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) { 1281 if (pFNode->mArrayNum > 0) { 1282 fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, 1283 pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName); 1284 } else { 1285 fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, 1286 pFNode->mFieldName, pFNode->mFieldType->mTypeName); 1287 } 1288 } 1289 fprintf (File, "\t\t};\n"); 1290 fprintf (File, "---------------------------------------------------------------\n"); 1291 } 1292 fprintf (File, "***************************************************************\n"); 1293 } 1294 1295 #ifdef CVFR_VARDATATYPEDB_DEBUG 1296 VOID 1297 CVfrVarDataTypeDB::ParserDB ( 1298 VOID 1299 ) 1300 { 1301 SVfrDataType *pTNode; 1302 SVfrDataField *pFNode; 1303 1304 printf ("***************************************************************\n"); 1305 printf ("\t\tmPackAlign = %x\n", mPackAlign); 1306 for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) { 1307 printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize); 1308 printf ("\t\tstruct %s {\n", pTNode->mTypeName); 1309 for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) { 1310 printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName); 1311 } 1312 printf ("\t\t};\n"); 1313 printf ("---------------------------------------------------------------\n"); 1314 } 1315 printf ("***************************************************************\n"); 1316 } 1317 #endif 1318 1319 SVfrVarStorageNode::SVfrVarStorageNode ( 1320 IN EFI_GUID *Guid, 1321 IN CHAR8 *StoreName, 1322 IN EFI_VARSTORE_ID VarStoreId, 1323 IN EFI_STRING_ID VarName, 1324 IN UINT32 VarSize, 1325 IN BOOLEAN Flag 1326 ) 1327 { 1328 if (Guid != NULL) { 1329 mGuid = *Guid; 1330 } else { 1331 memset (&mGuid, 0, sizeof (EFI_GUID)); 1332 } 1333 if (StoreName != NULL) { 1334 mVarStoreName = new CHAR8[strlen(StoreName) + 1]; 1335 strcpy (mVarStoreName, StoreName); 1336 } else { 1337 mVarStoreName = NULL; 1338 } 1339 mNext = NULL; 1340 mVarStoreId = VarStoreId; 1341 mVarStoreType = EFI_VFR_VARSTORE_EFI; 1342 mStorageInfo.mEfiVar.mEfiVarName = VarName; 1343 mStorageInfo.mEfiVar.mEfiVarSize = VarSize; 1344 mAssignedFlag = Flag; 1345 } 1346 1347 SVfrVarStorageNode::SVfrVarStorageNode ( 1348 IN EFI_GUID *Guid, 1349 IN CHAR8 *StoreName, 1350 IN EFI_VARSTORE_ID VarStoreId, 1351 IN SVfrDataType *DataType, 1352 IN BOOLEAN Flag 1353 ) 1354 { 1355 if (Guid != NULL) { 1356 mGuid = *Guid; 1357 } else { 1358 memset (&mGuid, 0, sizeof (EFI_GUID)); 1359 } 1360 if (StoreName != NULL) { 1361 mVarStoreName = new CHAR8[strlen(StoreName) + 1]; 1362 strcpy (mVarStoreName, StoreName); 1363 } else { 1364 mVarStoreName = NULL; 1365 } 1366 mNext = NULL; 1367 mVarStoreId = VarStoreId; 1368 mVarStoreType = EFI_VFR_VARSTORE_BUFFER; 1369 mStorageInfo.mDataType = DataType; 1370 mAssignedFlag = Flag; 1371 } 1372 1373 SVfrVarStorageNode::SVfrVarStorageNode ( 1374 IN CHAR8 *StoreName, 1375 IN EFI_VARSTORE_ID VarStoreId 1376 ) 1377 { 1378 if (StoreName != NULL) { 1379 mVarStoreName = new CHAR8[strlen(StoreName) + 1]; 1380 strcpy (mVarStoreName, StoreName); 1381 } else { 1382 mVarStoreName = NULL; 1383 } 1384 mNext = NULL; 1385 mVarStoreId = VarStoreId; 1386 mVarStoreType = EFI_VFR_VARSTORE_NAME; 1387 mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS]; 1388 mStorageInfo.mNameSpace.mTableSize = 0; 1389 } 1390 1391 SVfrVarStorageNode::~SVfrVarStorageNode ( 1392 VOID 1393 ) 1394 { 1395 if (mVarStoreName != NULL) { 1396 delete[] mVarStoreName; 1397 } 1398 1399 if (mVarStoreType == EFI_VFR_VARSTORE_NAME) { 1400 delete mStorageInfo.mNameSpace.mNameTable; 1401 } 1402 } 1403 1404 CVfrDataStorage::CVfrDataStorage ( 1405 VOID 1406 ) 1407 { 1408 UINT32 Index; 1409 1410 for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) { 1411 mFreeVarStoreIdBitMap[Index] = 0; 1412 } 1413 1414 // Question ID 0 is reserved. 1415 mFreeVarStoreIdBitMap[0] = 0x80000000; 1416 1417 mBufferVarStoreList = NULL; 1418 mEfiVarStoreList = NULL; 1419 mNameVarStoreList = NULL; 1420 mCurrVarStorageNode = NULL; 1421 mNewVarStorageNode = NULL; 1422 mBufferFieldInfoListHead = NULL; 1423 mBufferFieldInfoListTail = NULL; 1424 } 1425 1426 CVfrDataStorage::~CVfrDataStorage ( 1427 VOID 1428 ) 1429 { 1430 SVfrVarStorageNode *pNode; 1431 1432 while (mBufferVarStoreList != NULL) { 1433 pNode = mBufferVarStoreList; 1434 mBufferVarStoreList = mBufferVarStoreList->mNext; 1435 delete pNode; 1436 } 1437 while (mEfiVarStoreList != NULL) { 1438 pNode = mEfiVarStoreList; 1439 mEfiVarStoreList = mEfiVarStoreList->mNext; 1440 delete pNode; 1441 } 1442 while (mNameVarStoreList != NULL) { 1443 pNode = mNameVarStoreList; 1444 mNameVarStoreList = mNameVarStoreList->mNext; 1445 delete pNode; 1446 } 1447 if (mNewVarStorageNode != NULL) { 1448 delete mNewVarStorageNode; 1449 } 1450 } 1451 1452 EFI_VARSTORE_ID 1453 CVfrDataStorage::GetFreeVarStoreId ( 1454 EFI_VFR_VARSTORE_TYPE VarType 1455 ) 1456 { 1457 UINT32 Index, Mask, Offset; 1458 1459 // 1460 // Assign the different ID range for the different type VarStore to support Framework Vfr 1461 // 1462 Index = 0; 1463 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) { 1464 Index = 0; 1465 } else if (VarType == EFI_VFR_VARSTORE_EFI) { 1466 Index = 1; 1467 } else if (VarType == EFI_VFR_VARSTORE_NAME) { 1468 Index = 2; 1469 } 1470 1471 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) { 1472 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) { 1473 break; 1474 } 1475 } 1476 1477 if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) { 1478 return EFI_VARSTORE_ID_INVALID; 1479 } 1480 1481 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { 1482 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) { 1483 mFreeVarStoreIdBitMap[Index] |= Mask; 1484 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); 1485 } 1486 } 1487 1488 return EFI_VARSTORE_ID_INVALID; 1489 } 1490 1491 BOOLEAN 1492 CVfrDataStorage::ChekVarStoreIdFree ( 1493 IN EFI_VARSTORE_ID VarStoreId 1494 ) 1495 { 1496 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1497 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1498 1499 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0; 1500 } 1501 1502 VOID 1503 CVfrDataStorage::MarkVarStoreIdUsed ( 1504 IN EFI_VARSTORE_ID VarStoreId 1505 ) 1506 { 1507 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1508 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1509 1510 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset); 1511 } 1512 1513 VOID 1514 CVfrDataStorage::MarkVarStoreIdUnused ( 1515 IN EFI_VARSTORE_ID VarStoreId 1516 ) 1517 { 1518 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1519 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1520 1521 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset); 1522 } 1523 1524 EFI_VFR_RETURN_CODE 1525 CVfrDataStorage::DeclareNameVarStoreBegin ( 1526 IN CHAR8 *StoreName, 1527 IN EFI_VARSTORE_ID VarStoreId 1528 ) 1529 { 1530 SVfrVarStorageNode *pNode = NULL; 1531 EFI_VARSTORE_ID TmpVarStoreId; 1532 1533 if (StoreName == NULL) { 1534 return VFR_RETURN_FATAL_ERROR; 1535 } 1536 1537 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) { 1538 return VFR_RETURN_REDEFINED; 1539 } 1540 1541 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1542 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME); 1543 } else { 1544 if (ChekVarStoreIdFree (VarStoreId) == FALSE) { 1545 return VFR_RETURN_VARSTOREID_REDEFINED; 1546 } 1547 MarkVarStoreIdUsed (VarStoreId); 1548 } 1549 1550 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) { 1551 return VFR_RETURN_UNDEFINED; 1552 } 1553 1554 mNewVarStorageNode = pNode; 1555 1556 return VFR_RETURN_SUCCESS; 1557 } 1558 1559 EFI_VFR_RETURN_CODE 1560 CVfrDataStorage::NameTableAddItem ( 1561 IN EFI_STRING_ID Item 1562 ) 1563 { 1564 EFI_VARSTORE_ID *NewTable, *OldTable; 1565 UINT32 TableSize; 1566 1567 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable; 1568 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize; 1569 1570 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) { 1571 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) { 1572 return VFR_RETURN_OUT_FOR_RESOURCES; 1573 } 1574 memcpy (NewTable, OldTable, TableSize); 1575 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable; 1576 } 1577 1578 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item; 1579 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize; 1580 1581 return VFR_RETURN_SUCCESS; 1582 } 1583 1584 EFI_VFR_RETURN_CODE 1585 CVfrDataStorage::DeclareNameVarStoreEnd ( 1586 IN EFI_GUID *Guid 1587 ) 1588 { 1589 mNewVarStorageNode->mGuid = *Guid; 1590 mNewVarStorageNode->mNext = mNameVarStoreList; 1591 mNameVarStoreList = mNewVarStorageNode; 1592 1593 mNewVarStorageNode = NULL; 1594 1595 return VFR_RETURN_SUCCESS; 1596 } 1597 1598 EFI_VFR_RETURN_CODE 1599 CVfrDataStorage::DeclareEfiVarStore ( 1600 IN CHAR8 *StoreName, 1601 IN EFI_GUID *Guid, 1602 IN EFI_STRING_ID NameStrId, 1603 IN UINT32 VarSize, 1604 IN BOOLEAN Flag 1605 ) 1606 { 1607 SVfrVarStorageNode *pNode; 1608 EFI_VARSTORE_ID VarStoreId; 1609 1610 if ((StoreName == NULL) || (Guid == NULL)) { 1611 return VFR_RETURN_FATAL_ERROR; 1612 } 1613 1614 if (VarSize > sizeof (UINT64)) { 1615 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR; 1616 } 1617 1618 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) { 1619 return VFR_RETURN_REDEFINED; 1620 } 1621 1622 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI); 1623 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) { 1624 return VFR_RETURN_OUT_FOR_RESOURCES; 1625 } 1626 1627 pNode->mNext = mEfiVarStoreList; 1628 mEfiVarStoreList = pNode; 1629 1630 return VFR_RETURN_SUCCESS; 1631 } 1632 1633 EFI_VFR_RETURN_CODE 1634 CVfrDataStorage::DeclareBufferVarStore ( 1635 IN CHAR8 *StoreName, 1636 IN EFI_GUID *Guid, 1637 IN CVfrVarDataTypeDB *DataTypeDB, 1638 IN CHAR8 *TypeName, 1639 IN EFI_VARSTORE_ID VarStoreId, 1640 IN BOOLEAN Flag 1641 ) 1642 { 1643 SVfrVarStorageNode *pNew = NULL; 1644 SVfrDataType *pDataType = NULL; 1645 EFI_VARSTORE_ID TempVarStoreId; 1646 1647 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) { 1648 return VFR_RETURN_FATAL_ERROR; 1649 } 1650 1651 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) { 1652 return VFR_RETURN_REDEFINED; 1653 } 1654 1655 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS); 1656 1657 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1658 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER); 1659 } else { 1660 if (ChekVarStoreIdFree (VarStoreId) == FALSE) { 1661 return VFR_RETURN_VARSTOREID_REDEFINED; 1662 } 1663 MarkVarStoreIdUsed (VarStoreId); 1664 } 1665 1666 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) { 1667 return VFR_RETURN_OUT_FOR_RESOURCES; 1668 } 1669 1670 pNew->mNext = mBufferVarStoreList; 1671 mBufferVarStoreList = pNew; 1672 1673 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) { 1674 return VFR_RETURN_FATAL_ERROR; 1675 } 1676 1677 return VFR_RETURN_SUCCESS; 1678 } 1679 1680 EFI_VFR_RETURN_CODE 1681 CVfrDataStorage::GetVarStoreByDataType ( 1682 IN CHAR8 *DataTypeName, 1683 OUT SVfrVarStorageNode **VarNode, 1684 IN EFI_GUID *VarGuid 1685 ) 1686 { 1687 SVfrVarStorageNode *pNode; 1688 SVfrVarStorageNode *MatchNode; 1689 1690 // 1691 // Framework VFR uses Data type name as varstore name, so don't need check again. 1692 // 1693 if (VfrCompatibleMode) { 1694 return VFR_RETURN_UNDEFINED; 1695 } 1696 1697 MatchNode = NULL; 1698 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1699 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) { 1700 continue; 1701 } 1702 1703 if ((VarGuid != NULL)) { 1704 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) { 1705 *VarNode = pNode; 1706 return VFR_RETURN_SUCCESS; 1707 } 1708 } else { 1709 if (MatchNode == NULL) { 1710 MatchNode = pNode; 1711 } else { 1712 // 1713 // More than one varstores referred the same data structures. 1714 // 1715 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR; 1716 } 1717 } 1718 } 1719 1720 if (MatchNode == NULL) { 1721 return VFR_RETURN_UNDEFINED; 1722 } 1723 1724 *VarNode = MatchNode; 1725 return VFR_RETURN_SUCCESS; 1726 } 1727 1728 EFI_VARSTORE_ID 1729 CVfrDataStorage::CheckGuidField ( 1730 IN SVfrVarStorageNode *pNode, 1731 IN EFI_GUID *StoreGuid, 1732 IN BOOLEAN *HasFoundOne, 1733 OUT EFI_VFR_RETURN_CODE *ReturnCode 1734 ) 1735 { 1736 if (StoreGuid != NULL) { 1737 // 1738 // If has guid info, compare the guid filed. 1739 // 1740 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) { 1741 // 1742 // Both name and guid are same, this this varstore. 1743 // 1744 mCurrVarStorageNode = pNode; 1745 *ReturnCode = VFR_RETURN_SUCCESS; 1746 return TRUE; 1747 } 1748 } else { 1749 // 1750 // Not has Guid field, check whether this name is the only one. 1751 // 1752 if (*HasFoundOne) { 1753 // 1754 // The name has conflict, return name redefined. 1755 // 1756 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR; 1757 return TRUE; 1758 } 1759 1760 *HasFoundOne = TRUE; 1761 mCurrVarStorageNode = pNode; 1762 } 1763 1764 return FALSE; 1765 } 1766 1767 /** 1768 Base on the input store name and guid to find the varstore id. 1769 1770 If both name and guid are inputed, base on the name and guid to 1771 found the varstore. If only name inputed, base on the name to 1772 found the varstore and go on to check whether more than one varstore 1773 has the same name. If only has found one varstore, return this 1774 varstore; if more than one varstore has same name, return varstore 1775 name redefined error. If no varstore found by varstore name, call 1776 function GetVarStoreByDataType and use inputed varstore name as 1777 data type name to search. 1778 **/ 1779 EFI_VFR_RETURN_CODE 1780 CVfrDataStorage::GetVarStoreId ( 1781 IN CHAR8 *StoreName, 1782 OUT EFI_VARSTORE_ID *VarStoreId, 1783 IN EFI_GUID *StoreGuid 1784 ) 1785 { 1786 EFI_VFR_RETURN_CODE ReturnCode; 1787 SVfrVarStorageNode *pNode; 1788 BOOLEAN HasFoundOne = FALSE; 1789 1790 mCurrVarStorageNode = NULL; 1791 1792 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1793 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1794 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1795 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1796 return ReturnCode; 1797 } 1798 } 1799 } 1800 1801 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1802 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1803 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1804 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1805 return ReturnCode; 1806 } 1807 } 1808 } 1809 1810 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1811 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1812 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1813 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1814 return ReturnCode; 1815 } 1816 } 1817 } 1818 1819 if (HasFoundOne) { 1820 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1821 return VFR_RETURN_SUCCESS; 1822 } 1823 1824 *VarStoreId = EFI_VARSTORE_ID_INVALID; 1825 1826 // 1827 // Assume that Data strucutre name is used as StoreName, and check again. 1828 // 1829 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid); 1830 if (pNode != NULL) { 1831 mCurrVarStorageNode = pNode; 1832 *VarStoreId = pNode->mVarStoreId; 1833 } 1834 1835 return ReturnCode; 1836 } 1837 1838 EFI_VFR_RETURN_CODE 1839 CVfrDataStorage::GetBufferVarStoreDataTypeName ( 1840 IN EFI_VARSTORE_ID VarStoreId, 1841 OUT CHAR8 **DataTypeName 1842 ) 1843 { 1844 SVfrVarStorageNode *pNode; 1845 1846 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1847 return VFR_RETURN_FATAL_ERROR; 1848 } 1849 1850 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1851 if (pNode->mVarStoreId == VarStoreId) { 1852 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName; 1853 return VFR_RETURN_SUCCESS; 1854 } 1855 } 1856 1857 return VFR_RETURN_UNDEFINED; 1858 } 1859 1860 EFI_VFR_VARSTORE_TYPE 1861 CVfrDataStorage::GetVarStoreType ( 1862 IN EFI_VARSTORE_ID VarStoreId 1863 ) 1864 { 1865 SVfrVarStorageNode *pNode; 1866 EFI_VFR_VARSTORE_TYPE VarStoreType; 1867 1868 VarStoreType = EFI_VFR_VARSTORE_INVALID; 1869 1870 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1871 return VarStoreType; 1872 } 1873 1874 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1875 if (pNode->mVarStoreId == VarStoreId) { 1876 VarStoreType = pNode->mVarStoreType; 1877 return VarStoreType; 1878 } 1879 } 1880 1881 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1882 if (pNode->mVarStoreId == VarStoreId) { 1883 VarStoreType = pNode->mVarStoreType; 1884 return VarStoreType; 1885 } 1886 } 1887 1888 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1889 if (pNode->mVarStoreId == VarStoreId) { 1890 VarStoreType = pNode->mVarStoreType; 1891 return VarStoreType; 1892 } 1893 } 1894 1895 return VarStoreType; 1896 } 1897 1898 EFI_GUID * 1899 CVfrDataStorage::GetVarStoreGuid ( 1900 IN EFI_VARSTORE_ID VarStoreId 1901 ) 1902 { 1903 SVfrVarStorageNode *pNode; 1904 EFI_GUID *VarGuid; 1905 1906 VarGuid = NULL; 1907 1908 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1909 return VarGuid; 1910 } 1911 1912 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1913 if (pNode->mVarStoreId == VarStoreId) { 1914 VarGuid = &pNode->mGuid; 1915 return VarGuid; 1916 } 1917 } 1918 1919 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1920 if (pNode->mVarStoreId == VarStoreId) { 1921 VarGuid = &pNode->mGuid; 1922 return VarGuid; 1923 } 1924 } 1925 1926 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1927 if (pNode->mVarStoreId == VarStoreId) { 1928 VarGuid = &pNode->mGuid; 1929 return VarGuid; 1930 } 1931 } 1932 1933 return VarGuid; 1934 } 1935 1936 EFI_VFR_RETURN_CODE 1937 CVfrDataStorage::GetVarStoreName ( 1938 IN EFI_VARSTORE_ID VarStoreId, 1939 OUT CHAR8 **VarStoreName 1940 ) 1941 { 1942 SVfrVarStorageNode *pNode; 1943 1944 if (VarStoreName == NULL) { 1945 return VFR_RETURN_FATAL_ERROR; 1946 } 1947 1948 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1949 if (pNode->mVarStoreId == VarStoreId) { 1950 *VarStoreName = pNode->mVarStoreName; 1951 return VFR_RETURN_SUCCESS; 1952 } 1953 } 1954 1955 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1956 if (pNode->mVarStoreId == VarStoreId) { 1957 *VarStoreName = pNode->mVarStoreName; 1958 return VFR_RETURN_SUCCESS; 1959 } 1960 } 1961 1962 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1963 if (pNode->mVarStoreId == VarStoreId) { 1964 *VarStoreName = pNode->mVarStoreName; 1965 return VFR_RETURN_SUCCESS; 1966 } 1967 } 1968 1969 *VarStoreName = NULL; 1970 return VFR_RETURN_UNDEFINED; 1971 } 1972 1973 EFI_VFR_RETURN_CODE 1974 CVfrDataStorage::GetEfiVarStoreInfo ( 1975 IN OUT EFI_VARSTORE_INFO *Info 1976 ) 1977 { 1978 if (Info == NULL) { 1979 return VFR_RETURN_FATAL_ERROR; 1980 } 1981 1982 if (mCurrVarStorageNode == NULL) { 1983 return VFR_RETURN_GET_EFIVARSTORE_ERROR; 1984 } 1985 1986 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName; 1987 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize; 1988 switch (Info->mVarTotalSize) { 1989 case 1: 1990 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8; 1991 break; 1992 case 2: 1993 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16; 1994 break; 1995 case 4: 1996 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32; 1997 break; 1998 case 8: 1999 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64; 2000 break; 2001 default : 2002 return VFR_RETURN_FATAL_ERROR; 2003 } 2004 2005 return VFR_RETURN_SUCCESS; 2006 } 2007 2008 EFI_VFR_RETURN_CODE 2009 CVfrDataStorage::AddBufferVarStoreFieldInfo ( 2010 IN EFI_VARSTORE_INFO *Info 2011 ) 2012 { 2013 BufferVarStoreFieldInfoNode *pNew; 2014 2015 if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) { 2016 return VFR_RETURN_FATAL_ERROR; 2017 } 2018 2019 if (mBufferFieldInfoListHead == NULL) { 2020 mBufferFieldInfoListHead = pNew; 2021 mBufferFieldInfoListTail= pNew; 2022 } else { 2023 mBufferFieldInfoListTail->mNext = pNew; 2024 mBufferFieldInfoListTail = pNew; 2025 } 2026 2027 return VFR_RETURN_SUCCESS; 2028 } 2029 2030 EFI_VFR_RETURN_CODE 2031 CVfrDataStorage::GetBufferVarStoreFieldInfo ( 2032 IN OUT EFI_VARSTORE_INFO *Info 2033 ) 2034 { 2035 BufferVarStoreFieldInfoNode *pNode; 2036 2037 pNode = mBufferFieldInfoListHead; 2038 while (pNode != NULL) { 2039 if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId && 2040 Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) { 2041 Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize; 2042 Info->mVarType = pNode->mVarStoreInfo.mVarType; 2043 return VFR_RETURN_SUCCESS; 2044 } 2045 pNode = pNode->mNext; 2046 } 2047 return VFR_RETURN_FATAL_ERROR; 2048 } 2049 2050 EFI_VFR_RETURN_CODE 2051 CVfrDataStorage::GetNameVarStoreInfo ( 2052 OUT EFI_VARSTORE_INFO *Info, 2053 IN UINT32 Index 2054 ) 2055 { 2056 if (Info == NULL) { 2057 return VFR_RETURN_FATAL_ERROR; 2058 } 2059 2060 if (mCurrVarStorageNode == NULL) { 2061 return VFR_RETURN_GET_NVVARSTORE_ERROR; 2062 } 2063 2064 // 2065 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0. 2066 // 2067 if (VfrCompatibleMode) { 2068 if (Index == 0) { 2069 return VFR_RETURN_ERROR_ARRARY_NUM; 2070 } 2071 Index --; 2072 } 2073 2074 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index]; 2075 2076 return VFR_RETURN_SUCCESS; 2077 } 2078 2079 SVfrDefaultStoreNode::SVfrDefaultStoreNode ( 2080 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr, 2081 IN CHAR8 *RefName, 2082 IN EFI_STRING_ID DefaultStoreNameId, 2083 IN UINT16 DefaultId 2084 ) 2085 { 2086 mObjBinAddr = ObjBinAddr; 2087 2088 if (RefName != NULL) { 2089 mRefName = new CHAR8[strlen (RefName) + 1]; 2090 strcpy (mRefName, RefName); 2091 } else { 2092 mRefName = NULL; 2093 } 2094 2095 mNext = NULL; 2096 mDefaultId = DefaultId; 2097 mDefaultStoreNameId = DefaultStoreNameId; 2098 } 2099 2100 SVfrDefaultStoreNode::~SVfrDefaultStoreNode ( 2101 VOID 2102 ) 2103 { 2104 if (mRefName != NULL) { 2105 delete[] mRefName; 2106 } 2107 } 2108 2109 CVfrDefaultStore::CVfrDefaultStore ( 2110 VOID 2111 ) 2112 { 2113 mDefaultStoreList = NULL; 2114 } 2115 2116 CVfrDefaultStore::~CVfrDefaultStore ( 2117 VOID 2118 ) 2119 { 2120 SVfrDefaultStoreNode *pTmp = NULL; 2121 2122 while (mDefaultStoreList != NULL) { 2123 pTmp = mDefaultStoreList; 2124 mDefaultStoreList = mDefaultStoreList->mNext; 2125 delete pTmp; 2126 } 2127 } 2128 2129 EFI_VFR_RETURN_CODE 2130 CVfrDefaultStore::RegisterDefaultStore ( 2131 IN CHAR8 *ObjBinAddr, 2132 IN CHAR8 *RefName, 2133 IN EFI_STRING_ID DefaultStoreNameId, 2134 IN UINT16 DefaultId 2135 ) 2136 { 2137 SVfrDefaultStoreNode *pNode = NULL; 2138 2139 if (RefName == NULL) { 2140 return VFR_RETURN_FATAL_ERROR; 2141 } 2142 2143 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2144 if (strcmp (pNode->mRefName, RefName) == 0) { 2145 return VFR_RETURN_REDEFINED; 2146 } 2147 } 2148 2149 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) { 2150 return VFR_RETURN_OUT_FOR_RESOURCES; 2151 } 2152 2153 pNode->mNext = mDefaultStoreList; 2154 mDefaultStoreList = pNode; 2155 2156 return VFR_RETURN_SUCCESS; 2157 } 2158 2159 /* 2160 * assign new reference name or new default store name id only if 2161 * the original is invalid 2162 */ 2163 EFI_VFR_RETURN_CODE 2164 CVfrDefaultStore::ReRegisterDefaultStoreById ( 2165 IN UINT16 DefaultId, 2166 IN CHAR8 *RefName, 2167 IN EFI_STRING_ID DefaultStoreNameId 2168 ) 2169 { 2170 SVfrDefaultStoreNode *pNode = NULL; 2171 2172 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2173 if (pNode->mDefaultId == DefaultId) { 2174 break; 2175 } 2176 } 2177 2178 if (pNode == NULL) { 2179 return VFR_RETURN_UNDEFINED; 2180 } else { 2181 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) { 2182 pNode->mDefaultStoreNameId = DefaultStoreNameId; 2183 if (pNode->mObjBinAddr != NULL) { 2184 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId; 2185 } 2186 } else { 2187 return VFR_RETURN_REDEFINED; 2188 } 2189 2190 if (RefName != NULL) { 2191 delete pNode->mRefName; 2192 pNode->mRefName = new CHAR8[strlen (RefName) + 1]; 2193 if (pNode->mRefName != NULL) { 2194 strcpy (pNode->mRefName, RefName); 2195 } 2196 } 2197 } 2198 2199 return VFR_RETURN_SUCCESS; 2200 } 2201 2202 BOOLEAN 2203 CVfrDefaultStore::DefaultIdRegistered ( 2204 IN UINT16 DefaultId 2205 ) 2206 { 2207 SVfrDefaultStoreNode *pNode = NULL; 2208 2209 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2210 if (pNode->mDefaultId == DefaultId) { 2211 return TRUE; 2212 } 2213 } 2214 2215 return FALSE; 2216 } 2217 2218 EFI_VFR_RETURN_CODE 2219 CVfrDefaultStore::GetDefaultId ( 2220 IN CHAR8 *RefName, 2221 OUT UINT16 *DefaultId 2222 ) 2223 { 2224 SVfrDefaultStoreNode *pTmp = NULL; 2225 2226 if (DefaultId == NULL) { 2227 return VFR_RETURN_FATAL_ERROR; 2228 } 2229 2230 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) { 2231 if (strcmp (pTmp->mRefName, RefName) == 0) { 2232 *DefaultId = pTmp->mDefaultId; 2233 return VFR_RETURN_SUCCESS; 2234 } 2235 } 2236 2237 return VFR_RETURN_UNDEFINED; 2238 } 2239 2240 EFI_VFR_RETURN_CODE 2241 CVfrDefaultStore::BufferVarStoreAltConfigAdd ( 2242 IN EFI_VARSTORE_ID DefaultId, 2243 IN EFI_VARSTORE_INFO &Info, 2244 IN CHAR8 *VarStoreName, 2245 IN EFI_GUID *VarStoreGuid, 2246 IN UINT8 Type, 2247 IN EFI_IFR_TYPE_VALUE Value 2248 ) 2249 { 2250 SVfrDefaultStoreNode *pNode = NULL; 2251 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,}; 2252 INTN Returnvalue = 0; 2253 2254 if (VarStoreName == NULL) { 2255 return VFR_RETURN_FATAL_ERROR; 2256 } 2257 2258 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2259 if (pNode->mDefaultId == DefaultId) { 2260 break; 2261 } 2262 } 2263 2264 if (pNode == NULL) { 2265 return VFR_RETURN_UNDEFINED; 2266 } 2267 2268 gCVfrBufferConfig.Open (); 2269 2270 sprintf (NewAltCfg, "%04x", pNode->mDefaultId); 2271 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) { 2272 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) { 2273 goto WriteError; 2274 } 2275 } 2276 2277 gCVfrBufferConfig.Close (); 2278 2279 return VFR_RETURN_SUCCESS; 2280 2281 WriteError: 2282 gCVfrBufferConfig.Close (); 2283 return (EFI_VFR_RETURN_CODE)Returnvalue; 2284 } 2285 2286 SVfrRuleNode::SVfrRuleNode ( 2287 IN CHAR8 *RuleName, 2288 IN UINT8 RuleId 2289 ) 2290 { 2291 if (RuleName != NULL) { 2292 mRuleName = new CHAR8[strlen (RuleName) + 1]; 2293 strcpy (mRuleName, RuleName); 2294 } else { 2295 mRuleName = NULL; 2296 } 2297 2298 mNext = NULL; 2299 mRuleId = RuleId; 2300 } 2301 2302 SVfrRuleNode::~SVfrRuleNode ( 2303 VOID 2304 ) 2305 { 2306 if (mRuleName != NULL) { 2307 delete[] mRuleName; 2308 } 2309 } 2310 2311 CVfrRulesDB::CVfrRulesDB () 2312 { 2313 mRuleList = NULL; 2314 mFreeRuleId = EFI_VARSTORE_ID_START; 2315 } 2316 2317 CVfrRulesDB::~CVfrRulesDB () 2318 { 2319 SVfrRuleNode *pNode; 2320 2321 while(mRuleList != NULL) { 2322 pNode = mRuleList; 2323 mRuleList = mRuleList->mNext; 2324 delete pNode; 2325 } 2326 } 2327 2328 VOID 2329 CVfrRulesDB::RegisterRule ( 2330 IN CHAR8 *RuleName 2331 ) 2332 { 2333 SVfrRuleNode *pNew; 2334 2335 if (RuleName == NULL) { 2336 return ; 2337 } 2338 2339 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) { 2340 return ; 2341 } 2342 2343 mFreeRuleId++; 2344 2345 pNew->mNext = mRuleList; 2346 mRuleList = pNew; 2347 } 2348 2349 UINT8 2350 CVfrRulesDB::GetRuleId ( 2351 IN CHAR8 *RuleName 2352 ) 2353 { 2354 SVfrRuleNode *pNode; 2355 2356 if (RuleName == NULL) { 2357 return EFI_RULE_ID_INVALID; 2358 } 2359 2360 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) { 2361 if (strcmp (pNode->mRuleName, RuleName) == 0) { 2362 return pNode->mRuleId; 2363 } 2364 } 2365 2366 return EFI_RULE_ID_INVALID; 2367 } 2368 2369 CVfrRulesDB gCVfrRulesDB; 2370 2371 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( 2372 VOID 2373 ) 2374 { 2375 mVarStoreId = EFI_VARSTORE_ID_INVALID; 2376 mInfo.mVarName = EFI_STRING_ID_INVALID; 2377 mInfo.mVarOffset = EFI_VAROFFSET_INVALID; 2378 mVarType = EFI_IFR_TYPE_OTHER; 2379 mVarTotalSize = 0; 2380 } 2381 2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( 2383 IN EFI_VARSTORE_INFO &Info 2384 ) 2385 { 2386 mVarStoreId = Info.mVarStoreId; 2387 mInfo.mVarName = Info.mInfo.mVarName; 2388 mInfo.mVarOffset = Info.mInfo.mVarOffset; 2389 mVarType = Info.mVarType; 2390 mVarTotalSize = Info.mVarTotalSize; 2391 } 2392 2393 EFI_VARSTORE_INFO& 2394 EFI_VARSTORE_INFO::operator= ( 2395 IN CONST EFI_VARSTORE_INFO &Info 2396 ) 2397 { 2398 if (this != &Info) { 2399 mVarStoreId = Info.mVarStoreId; 2400 mInfo.mVarName = Info.mInfo.mVarName; 2401 mInfo.mVarOffset = Info.mInfo.mVarOffset; 2402 mVarType = Info.mVarType; 2403 mVarTotalSize = Info.mVarTotalSize; 2404 } 2405 2406 return *this; 2407 } 2408 2409 BOOLEAN 2410 EFI_VARSTORE_INFO::operator == ( 2411 IN EFI_VARSTORE_INFO *Info 2412 ) 2413 { 2414 if ((mVarStoreId == Info->mVarStoreId) && 2415 (mInfo.mVarName == Info->mInfo.mVarName) && 2416 (mInfo.mVarOffset == Info->mInfo.mVarOffset) && 2417 (mVarType == Info->mVarType) && 2418 (mVarTotalSize == Info->mVarTotalSize)) { 2419 return TRUE; 2420 } 2421 2422 return FALSE; 2423 } 2424 2425 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode( 2426 IN EFI_VARSTORE_INFO *Info 2427 ) 2428 { 2429 mVarStoreInfo.mVarType = Info->mVarType; 2430 mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize; 2431 mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset; 2432 mVarStoreInfo.mVarStoreId = Info->mVarStoreId; 2433 mNext = NULL; 2434 } 2435 2436 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode () 2437 { 2438 mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER; 2439 mVarStoreInfo.mVarTotalSize = 0; 2440 mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID; 2441 mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID; 2442 mNext = NULL; 2443 } 2444 2445 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo; 2446 2447 EFI_QUESTION_ID 2448 CVfrQuestionDB::GetFreeQuestionId ( 2449 VOID 2450 ) 2451 { 2452 UINT32 Index, Mask, Offset; 2453 2454 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2455 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) { 2456 break; 2457 } 2458 } 2459 2460 if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) { 2461 return EFI_QUESTION_ID_INVALID; 2462 } 2463 2464 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { 2465 if ((mFreeQIdBitMap[Index] & Mask) == 0) { 2466 mFreeQIdBitMap[Index] |= Mask; 2467 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); 2468 } 2469 } 2470 2471 return EFI_QUESTION_ID_INVALID; 2472 } 2473 2474 BOOLEAN 2475 CVfrQuestionDB::ChekQuestionIdFree ( 2476 IN EFI_QUESTION_ID QId 2477 ) 2478 { 2479 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2480 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2481 2482 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0; 2483 } 2484 2485 VOID 2486 CVfrQuestionDB::MarkQuestionIdUsed ( 2487 IN EFI_QUESTION_ID QId 2488 ) 2489 { 2490 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2491 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2492 2493 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset); 2494 } 2495 2496 VOID 2497 CVfrQuestionDB::MarkQuestionIdUnused ( 2498 IN EFI_QUESTION_ID QId 2499 ) 2500 { 2501 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2502 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2503 2504 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset); 2505 } 2506 2507 SVfrQuestionNode::SVfrQuestionNode ( 2508 IN CHAR8 *Name, 2509 IN CHAR8 *VarIdStr, 2510 IN UINT32 BitMask 2511 ) 2512 { 2513 mName = NULL; 2514 mVarIdStr = NULL; 2515 mQuestionId = EFI_QUESTION_ID_INVALID; 2516 mBitMask = BitMask; 2517 mNext = NULL; 2518 mQtype = QUESTION_NORMAL; 2519 2520 if (Name == NULL) { 2521 mName = new CHAR8[strlen ("$DEFAULT") + 1]; 2522 strcpy (mName, "$DEFAULT"); 2523 } else { 2524 mName = new CHAR8[strlen (Name) + 1]; 2525 strcpy (mName, Name); 2526 } 2527 2528 if (VarIdStr != NULL) { 2529 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1]; 2530 strcpy (mVarIdStr, VarIdStr); 2531 } else { 2532 mVarIdStr = new CHAR8[strlen ("$") + 1]; 2533 strcpy (mVarIdStr, "$"); 2534 } 2535 } 2536 2537 SVfrQuestionNode::~SVfrQuestionNode ( 2538 VOID 2539 ) 2540 { 2541 if (mName != NULL) { 2542 delete[] mName; 2543 } 2544 2545 if (mVarIdStr != NULL) { 2546 delete[] mVarIdStr; 2547 } 2548 } 2549 2550 CVfrQuestionDB::CVfrQuestionDB () 2551 { 2552 UINT32 Index; 2553 2554 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2555 mFreeQIdBitMap[Index] = 0; 2556 } 2557 2558 // Question ID 0 is reserved. 2559 mFreeQIdBitMap[0] = 0x80000000; 2560 mQuestionList = NULL; 2561 } 2562 2563 CVfrQuestionDB::~CVfrQuestionDB () 2564 { 2565 SVfrQuestionNode *pNode; 2566 2567 while (mQuestionList != NULL) { 2568 pNode = mQuestionList; 2569 mQuestionList = mQuestionList->mNext; 2570 delete pNode; 2571 } 2572 } 2573 2574 // 2575 // Reset to init state 2576 // 2577 VOID 2578 CVfrQuestionDB::ResetInit( 2579 IN VOID 2580 ) 2581 { 2582 UINT32 Index; 2583 SVfrQuestionNode *pNode; 2584 2585 while (mQuestionList != NULL) { 2586 pNode = mQuestionList; 2587 mQuestionList = mQuestionList->mNext; 2588 delete pNode; 2589 } 2590 2591 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2592 mFreeQIdBitMap[Index] = 0; 2593 } 2594 2595 // Question ID 0 is reserved. 2596 mFreeQIdBitMap[0] = 0x80000000; 2597 mQuestionList = NULL; 2598 } 2599 2600 VOID 2601 CVfrQuestionDB::PrintAllQuestion ( 2602 VOID 2603 ) 2604 { 2605 SVfrQuestionNode *pNode = NULL; 2606 2607 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 2608 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId); 2609 } 2610 } 2611 2612 EFI_VFR_RETURN_CODE 2613 CVfrQuestionDB::RegisterQuestion ( 2614 IN CHAR8 *Name, 2615 IN CHAR8 *VarIdStr, 2616 IN OUT EFI_QUESTION_ID &QuestionId 2617 ) 2618 { 2619 SVfrQuestionNode *pNode = NULL; 2620 2621 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) { 2622 return VFR_RETURN_REDEFINED; 2623 } 2624 2625 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) { 2626 return VFR_RETURN_OUT_FOR_RESOURCES; 2627 } 2628 2629 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2630 QuestionId = GetFreeQuestionId (); 2631 } else { 2632 // 2633 // For Framework Vfr, don't check question ID conflict. 2634 // 2635 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) { 2636 delete pNode; 2637 return VFR_RETURN_QUESTIONID_REDEFINED; 2638 } 2639 MarkQuestionIdUsed (QuestionId); 2640 } 2641 pNode->mQuestionId = QuestionId; 2642 2643 pNode->mNext = mQuestionList; 2644 mQuestionList = pNode; 2645 2646 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2647 2648 return VFR_RETURN_SUCCESS; 2649 } 2650 2651 VOID 2652 CVfrQuestionDB::RegisterOldDateQuestion ( 2653 IN CHAR8 *YearVarId, 2654 IN CHAR8 *MonthVarId, 2655 IN CHAR8 *DayVarId, 2656 IN OUT EFI_QUESTION_ID &QuestionId 2657 ) 2658 { 2659 SVfrQuestionNode *pNode[3] = {NULL, }; 2660 UINT32 Index; 2661 2662 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) { 2663 return; 2664 } 2665 2666 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) { 2667 goto Err; 2668 } 2669 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) { 2670 goto Err; 2671 } 2672 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) { 2673 goto Err; 2674 } 2675 2676 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2677 QuestionId = GetFreeQuestionId (); 2678 } else { 2679 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2680 goto Err; 2681 } 2682 MarkQuestionIdUsed (QuestionId); 2683 } 2684 2685 pNode[0]->mQuestionId = QuestionId; 2686 pNode[1]->mQuestionId = QuestionId; 2687 pNode[2]->mQuestionId = QuestionId; 2688 pNode[0]->mQtype = QUESTION_DATE; 2689 pNode[1]->mQtype = QUESTION_DATE; 2690 pNode[2]->mQtype = QUESTION_DATE; 2691 pNode[0]->mNext = pNode[1]; 2692 pNode[1]->mNext = pNode[2]; 2693 pNode[2]->mNext = mQuestionList; 2694 mQuestionList = pNode[0]; 2695 2696 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2697 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2698 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2699 2700 return; 2701 2702 Err: 2703 for (Index = 0; Index < 3; Index++) { 2704 if (pNode[Index] != NULL) { 2705 delete pNode[Index]; 2706 } 2707 } 2708 QuestionId = EFI_QUESTION_ID_INVALID; 2709 } 2710 2711 VOID 2712 CVfrQuestionDB::RegisterNewDateQuestion ( 2713 IN CHAR8 *Name, 2714 IN CHAR8 *BaseVarId, 2715 IN OUT EFI_QUESTION_ID &QuestionId 2716 ) 2717 { 2718 SVfrQuestionNode *pNode[3] = {NULL, }; 2719 UINT32 Len; 2720 CHAR8 *VarIdStr[3] = {NULL, }; 2721 CHAR8 Index; 2722 2723 if (BaseVarId == NULL && Name == NULL) { 2724 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2725 QuestionId = GetFreeQuestionId (); 2726 } else { 2727 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2728 goto Err; 2729 } 2730 MarkQuestionIdUsed (QuestionId); 2731 } 2732 return; 2733 } 2734 2735 if (BaseVarId != NULL) { 2736 Len = strlen (BaseVarId); 2737 2738 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1]; 2739 if (VarIdStr[0] != NULL) { 2740 strcpy (VarIdStr[0], BaseVarId); 2741 strcat (VarIdStr[0], ".Year"); 2742 } 2743 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1]; 2744 if (VarIdStr[1] != NULL) { 2745 strcpy (VarIdStr[1], BaseVarId); 2746 strcat (VarIdStr[1], ".Month"); 2747 } 2748 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1]; 2749 if (VarIdStr[2] != NULL) { 2750 strcpy (VarIdStr[2], BaseVarId); 2751 strcat (VarIdStr[2], ".Day"); 2752 } 2753 } else { 2754 Len = strlen (Name); 2755 2756 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1]; 2757 if (VarIdStr[0] != NULL) { 2758 strcpy (VarIdStr[0], Name); 2759 strcat (VarIdStr[0], ".Year"); 2760 } 2761 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1]; 2762 if (VarIdStr[1] != NULL) { 2763 strcpy (VarIdStr[1], Name); 2764 strcat (VarIdStr[1], ".Month"); 2765 } 2766 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1]; 2767 if (VarIdStr[2] != NULL) { 2768 strcpy (VarIdStr[2], Name); 2769 strcat (VarIdStr[2], ".Day"); 2770 } 2771 } 2772 2773 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) { 2774 goto Err; 2775 } 2776 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) { 2777 goto Err; 2778 } 2779 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) { 2780 goto Err; 2781 } 2782 2783 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2784 QuestionId = GetFreeQuestionId (); 2785 } else { 2786 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2787 goto Err; 2788 } 2789 MarkQuestionIdUsed (QuestionId); 2790 } 2791 2792 pNode[0]->mQuestionId = QuestionId; 2793 pNode[1]->mQuestionId = QuestionId; 2794 pNode[2]->mQuestionId = QuestionId; 2795 pNode[0]->mQtype = QUESTION_DATE; 2796 pNode[1]->mQtype = QUESTION_DATE; 2797 pNode[2]->mQtype = QUESTION_DATE; 2798 pNode[0]->mNext = pNode[1]; 2799 pNode[1]->mNext = pNode[2]; 2800 pNode[2]->mNext = mQuestionList; 2801 mQuestionList = pNode[0]; 2802 2803 for (Index = 0; Index < 3; Index++) { 2804 if (VarIdStr[Index] != NULL) { 2805 delete VarIdStr[Index]; 2806 } 2807 } 2808 2809 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2810 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2811 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2812 2813 return; 2814 2815 Err: 2816 for (Index = 0; Index < 3; Index++) { 2817 if (pNode[Index] != NULL) { 2818 delete pNode[Index]; 2819 } 2820 2821 if (VarIdStr[Index] != NULL) { 2822 delete VarIdStr[Index]; 2823 } 2824 } 2825 } 2826 2827 VOID 2828 CVfrQuestionDB::RegisterOldTimeQuestion ( 2829 IN CHAR8 *HourVarId, 2830 IN CHAR8 *MinuteVarId, 2831 IN CHAR8 *SecondVarId, 2832 IN OUT EFI_QUESTION_ID &QuestionId 2833 ) 2834 { 2835 SVfrQuestionNode *pNode[3] = {NULL, }; 2836 UINT32 Index; 2837 2838 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) { 2839 return; 2840 } 2841 2842 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) { 2843 goto Err; 2844 } 2845 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) { 2846 goto Err; 2847 } 2848 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) { 2849 goto Err; 2850 } 2851 2852 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2853 QuestionId = GetFreeQuestionId (); 2854 } else { 2855 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2856 goto Err; 2857 } 2858 MarkQuestionIdUsed (QuestionId); 2859 } 2860 2861 pNode[0]->mQuestionId = QuestionId; 2862 pNode[1]->mQuestionId = QuestionId; 2863 pNode[2]->mQuestionId = QuestionId; 2864 pNode[0]->mQtype = QUESTION_TIME; 2865 pNode[1]->mQtype = QUESTION_TIME; 2866 pNode[2]->mQtype = QUESTION_TIME; 2867 pNode[0]->mNext = pNode[1]; 2868 pNode[1]->mNext = pNode[2]; 2869 pNode[2]->mNext = mQuestionList; 2870 mQuestionList = pNode[0]; 2871 2872 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2873 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2874 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2875 2876 return; 2877 2878 Err: 2879 for (Index = 0; Index < 3; Index++) { 2880 if (pNode[Index] != NULL) { 2881 delete pNode[Index]; 2882 } 2883 } 2884 QuestionId = EFI_QUESTION_ID_INVALID; 2885 } 2886 2887 VOID 2888 CVfrQuestionDB::RegisterNewTimeQuestion ( 2889 IN CHAR8 *Name, 2890 IN CHAR8 *BaseVarId, 2891 IN OUT EFI_QUESTION_ID &QuestionId 2892 ) 2893 { 2894 SVfrQuestionNode *pNode[3] = {NULL, }; 2895 UINT32 Len; 2896 CHAR8 *VarIdStr[3] = {NULL, }; 2897 CHAR8 Index; 2898 2899 if (BaseVarId == NULL && Name == NULL) { 2900 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2901 QuestionId = GetFreeQuestionId (); 2902 } else { 2903 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2904 goto Err; 2905 } 2906 MarkQuestionIdUsed (QuestionId); 2907 } 2908 return; 2909 } 2910 2911 if (BaseVarId != NULL) { 2912 Len = strlen (BaseVarId); 2913 2914 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1]; 2915 if (VarIdStr[0] != NULL) { 2916 strcpy (VarIdStr[0], BaseVarId); 2917 strcat (VarIdStr[0], ".Hour"); 2918 } 2919 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1]; 2920 if (VarIdStr[1] != NULL) { 2921 strcpy (VarIdStr[1], BaseVarId); 2922 strcat (VarIdStr[1], ".Minute"); 2923 } 2924 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1]; 2925 if (VarIdStr[2] != NULL) { 2926 strcpy (VarIdStr[2], BaseVarId); 2927 strcat (VarIdStr[2], ".Second"); 2928 } 2929 } else { 2930 Len = strlen (Name); 2931 2932 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1]; 2933 if (VarIdStr[0] != NULL) { 2934 strcpy (VarIdStr[0], Name); 2935 strcat (VarIdStr[0], ".Hour"); 2936 } 2937 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1]; 2938 if (VarIdStr[1] != NULL) { 2939 strcpy (VarIdStr[1], Name); 2940 strcat (VarIdStr[1], ".Minute"); 2941 } 2942 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1]; 2943 if (VarIdStr[2] != NULL) { 2944 strcpy (VarIdStr[2], Name); 2945 strcat (VarIdStr[2], ".Second"); 2946 } 2947 } 2948 2949 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) { 2950 goto Err; 2951 } 2952 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) { 2953 goto Err; 2954 } 2955 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) { 2956 goto Err; 2957 } 2958 2959 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2960 QuestionId = GetFreeQuestionId (); 2961 } else { 2962 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2963 goto Err; 2964 } 2965 MarkQuestionIdUsed (QuestionId); 2966 } 2967 2968 pNode[0]->mQuestionId = QuestionId; 2969 pNode[1]->mQuestionId = QuestionId; 2970 pNode[2]->mQuestionId = QuestionId; 2971 pNode[0]->mQtype = QUESTION_TIME; 2972 pNode[1]->mQtype = QUESTION_TIME; 2973 pNode[2]->mQtype = QUESTION_TIME; 2974 pNode[0]->mNext = pNode[1]; 2975 pNode[1]->mNext = pNode[2]; 2976 pNode[2]->mNext = mQuestionList; 2977 mQuestionList = pNode[0]; 2978 2979 for (Index = 0; Index < 3; Index++) { 2980 if (VarIdStr[Index] != NULL) { 2981 delete VarIdStr[Index]; 2982 } 2983 } 2984 2985 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2986 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2987 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2988 2989 return; 2990 2991 Err: 2992 for (Index = 0; Index < 3; Index++) { 2993 if (pNode[Index] != NULL) { 2994 delete pNode[Index]; 2995 } 2996 2997 if (VarIdStr[Index] != NULL) { 2998 delete VarIdStr[Index]; 2999 } 3000 } 3001 } 3002 3003 VOID 3004 CVfrQuestionDB::RegisterRefQuestion ( 3005 IN CHAR8 *Name, 3006 IN CHAR8 *BaseVarId, 3007 IN OUT EFI_QUESTION_ID &QuestionId 3008 ) 3009 { 3010 SVfrQuestionNode *pNode[4] = {NULL, }; 3011 UINT32 Len; 3012 CHAR8 *VarIdStr[4] = {NULL, }; 3013 CHAR8 Index; 3014 3015 if (BaseVarId == NULL && Name == NULL) { 3016 return; 3017 } 3018 3019 if (BaseVarId != NULL) { 3020 Len = strlen (BaseVarId); 3021 3022 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1]; 3023 if (VarIdStr[0] != NULL) { 3024 strcpy (VarIdStr[0], BaseVarId); 3025 strcat (VarIdStr[0], ".QuestionId"); 3026 } 3027 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1]; 3028 if (VarIdStr[1] != NULL) { 3029 strcpy (VarIdStr[1], BaseVarId); 3030 strcat (VarIdStr[1], ".FormId"); 3031 } 3032 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1]; 3033 if (VarIdStr[2] != NULL) { 3034 strcpy (VarIdStr[2], BaseVarId); 3035 strcat (VarIdStr[2], ".FormSetGuid"); 3036 } 3037 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1]; 3038 if (VarIdStr[3] != NULL) { 3039 strcpy (VarIdStr[3], BaseVarId); 3040 strcat (VarIdStr[3], ".DevicePath"); 3041 } 3042 } else { 3043 Len = strlen (Name); 3044 3045 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1]; 3046 if (VarIdStr[0] != NULL) { 3047 strcpy (VarIdStr[0], Name); 3048 strcat (VarIdStr[0], ".QuestionId"); 3049 } 3050 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1]; 3051 if (VarIdStr[1] != NULL) { 3052 strcpy (VarIdStr[1], Name); 3053 strcat (VarIdStr[1], ".FormId"); 3054 } 3055 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1]; 3056 if (VarIdStr[2] != NULL) { 3057 strcpy (VarIdStr[2], Name); 3058 strcat (VarIdStr[2], ".FormSetGuid"); 3059 } 3060 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1]; 3061 if (VarIdStr[3] != NULL) { 3062 strcpy (VarIdStr[3], Name); 3063 strcat (VarIdStr[3], ".DevicePath"); 3064 } 3065 } 3066 3067 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) { 3068 goto Err; 3069 } 3070 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) { 3071 goto Err; 3072 } 3073 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) { 3074 goto Err; 3075 } 3076 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) { 3077 goto Err; 3078 } 3079 3080 if (QuestionId == EFI_QUESTION_ID_INVALID) { 3081 QuestionId = GetFreeQuestionId (); 3082 } else { 3083 if (ChekQuestionIdFree (QuestionId) == FALSE) { 3084 goto Err; 3085 } 3086 MarkQuestionIdUsed (QuestionId); 3087 } 3088 3089 pNode[0]->mQuestionId = QuestionId; 3090 pNode[1]->mQuestionId = QuestionId; 3091 pNode[2]->mQuestionId = QuestionId; 3092 pNode[3]->mQuestionId = QuestionId; 3093 pNode[0]->mQtype = QUESTION_REF; 3094 pNode[1]->mQtype = QUESTION_REF; 3095 pNode[2]->mQtype = QUESTION_REF; 3096 pNode[3]->mQtype = QUESTION_REF; 3097 pNode[0]->mNext = pNode[1]; 3098 pNode[1]->mNext = pNode[2]; 3099 pNode[2]->mNext = pNode[3]; 3100 pNode[3]->mNext = mQuestionList; 3101 mQuestionList = pNode[0]; 3102 3103 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3104 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3105 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3106 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3107 3108 return; 3109 3110 Err: 3111 for (Index = 0; Index < 4; Index++) { 3112 if (pNode[Index] != NULL) { 3113 delete pNode[Index]; 3114 } 3115 3116 if (VarIdStr[Index] != NULL) { 3117 delete VarIdStr[Index]; 3118 } 3119 } 3120 } 3121 3122 EFI_VFR_RETURN_CODE 3123 CVfrQuestionDB::UpdateQuestionId ( 3124 IN EFI_QUESTION_ID QId, 3125 IN EFI_QUESTION_ID NewQId 3126 ) 3127 { 3128 SVfrQuestionNode *pNode = NULL; 3129 3130 if (QId == NewQId) { 3131 // don't update 3132 return VFR_RETURN_SUCCESS; 3133 } 3134 3135 // 3136 // For Framework Vfr, don't check question ID conflict. 3137 // 3138 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) { 3139 return VFR_RETURN_REDEFINED; 3140 } 3141 3142 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3143 if (pNode->mQuestionId == QId) { 3144 break; 3145 } 3146 } 3147 3148 if (pNode == NULL) { 3149 return VFR_RETURN_UNDEFINED; 3150 } 3151 3152 MarkQuestionIdUnused (QId); 3153 pNode->mQuestionId = NewQId; 3154 MarkQuestionIdUsed (NewQId); 3155 3156 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID)); 3157 3158 return VFR_RETURN_SUCCESS; 3159 } 3160 3161 VOID 3162 CVfrQuestionDB::GetQuestionId ( 3163 IN CHAR8 *Name, 3164 IN CHAR8 *VarIdStr, 3165 OUT EFI_QUESTION_ID &QuestionId, 3166 OUT UINT32 &BitMask, 3167 OUT EFI_QUESION_TYPE *QType 3168 ) 3169 { 3170 SVfrQuestionNode *pNode; 3171 3172 QuestionId = EFI_QUESTION_ID_INVALID; 3173 BitMask = 0x00000000; 3174 if (QType != NULL) { 3175 *QType = QUESTION_NORMAL; 3176 } 3177 3178 if ((Name == NULL) && (VarIdStr == NULL)) { 3179 return ; 3180 } 3181 3182 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3183 if (Name != NULL) { 3184 if (strcmp (pNode->mName, Name) != 0) { 3185 continue; 3186 } 3187 } 3188 3189 if (VarIdStr != NULL) { 3190 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) { 3191 continue; 3192 } 3193 } 3194 3195 QuestionId = pNode->mQuestionId; 3196 BitMask = pNode->mBitMask; 3197 if (QType != NULL) { 3198 *QType = pNode->mQtype; 3199 } 3200 break; 3201 } 3202 3203 return ; 3204 } 3205 3206 EFI_VFR_RETURN_CODE 3207 CVfrQuestionDB::FindQuestion ( 3208 IN EFI_QUESTION_ID QuestionId 3209 ) 3210 { 3211 SVfrQuestionNode *pNode; 3212 3213 if (QuestionId == EFI_QUESTION_ID_INVALID) { 3214 return VFR_RETURN_INVALID_PARAMETER; 3215 } 3216 3217 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3218 if (pNode->mQuestionId == QuestionId) { 3219 return VFR_RETURN_SUCCESS; 3220 } 3221 } 3222 3223 return VFR_RETURN_UNDEFINED; 3224 } 3225 3226 EFI_VFR_RETURN_CODE 3227 CVfrQuestionDB::FindQuestion ( 3228 IN CHAR8 *Name 3229 ) 3230 { 3231 SVfrQuestionNode *pNode; 3232 3233 if (Name == NULL) { 3234 return VFR_RETURN_FATAL_ERROR; 3235 } 3236 3237 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3238 if (strcmp (pNode->mName, Name) == 0) { 3239 return VFR_RETURN_SUCCESS; 3240 } 3241 } 3242 3243 return VFR_RETURN_UNDEFINED; 3244 } 3245 3246 CVfrStringDB::CVfrStringDB () 3247 { 3248 mStringFileName = NULL; 3249 } 3250 3251 CVfrStringDB::~CVfrStringDB () 3252 { 3253 if (mStringFileName != NULL) { 3254 delete mStringFileName; 3255 } 3256 mStringFileName = NULL; 3257 } 3258 3259 3260 VOID 3261 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName) 3262 { 3263 UINT32 FileLen = 0; 3264 3265 if (StringFileName == NULL) { 3266 return; 3267 } 3268 3269 FileLen = strlen (StringFileName) + 1; 3270 mStringFileName = new CHAR8[FileLen]; 3271 if (mStringFileName == NULL) { 3272 return; 3273 } 3274 3275 strcpy (mStringFileName, StringFileName); 3276 mStringFileName[FileLen - 1] = '\0'; 3277 } 3278 3279 3280 /** 3281 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language 3282 from a set of supported languages. 3283 3284 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that 3285 contains a set of language codes. 3286 @param[in] Language A variable that contains pointers to Null-terminated 3287 ASCII strings that contain one language codes. 3288 3289 @retval FALSE The best matching language could not be found in SupportedLanguages. 3290 @retval TRUE The best matching language could be found in SupportedLanguages. 3291 3292 **/ 3293 BOOLEAN 3294 CVfrStringDB::GetBestLanguage ( 3295 IN CONST CHAR8 *SupportedLanguages, 3296 IN CHAR8 *Language 3297 ) 3298 { 3299 UINTN CompareLength; 3300 UINTN LanguageLength; 3301 CONST CHAR8 *Supported; 3302 3303 if (SupportedLanguages == NULL || Language == NULL){ 3304 return FALSE; 3305 } 3306 3307 // 3308 // Determine the length of the first RFC 4646 language code in Language 3309 // 3310 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++); 3311 3312 // 3313 // Trim back the length of Language used until it is empty 3314 // 3315 while (LanguageLength > 0) { 3316 // 3317 // Loop through all language codes in SupportedLanguages 3318 // 3319 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) { 3320 // 3321 // Skip ';' characters in Supported 3322 // 3323 for (; *Supported != '\0' && *Supported == ';'; Supported++); 3324 // 3325 // Determine the length of the next language code in Supported 3326 // 3327 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++); 3328 // 3329 // If Language is longer than the Supported, then skip to the next language 3330 // 3331 if (LanguageLength > CompareLength) { 3332 continue; 3333 } 3334 3335 // 3336 // See if the first LanguageLength characters in Supported match Language 3337 // 3338 if (strncmp (Supported, Language, LanguageLength) == 0) { 3339 return TRUE; 3340 } 3341 } 3342 3343 // 3344 // Trim Language from the right to the next '-' character 3345 // 3346 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--); 3347 } 3348 3349 // 3350 // No matches were found 3351 // 3352 return FALSE; 3353 } 3354 3355 3356 CHAR8 * 3357 CVfrStringDB::GetVarStoreNameFormStringId ( 3358 IN EFI_STRING_ID StringId 3359 ) 3360 { 3361 FILE *pInFile = NULL; 3362 UINT32 NameOffset; 3363 UINT32 Length; 3364 UINT8 *StringPtr; 3365 CHAR8 *StringName; 3366 CHAR16 *UnicodeString; 3367 CHAR8 *VarStoreName = NULL; 3368 CHAR8 *DestTmp; 3369 UINT8 *Current; 3370 EFI_STATUS Status; 3371 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH]; 3372 UINT8 BlockType; 3373 EFI_HII_STRING_PACKAGE_HDR *PkgHeader; 3374 3375 if (mStringFileName == NULL) { 3376 return NULL; 3377 } 3378 3379 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) { 3380 return NULL; 3381 } 3382 3383 // 3384 // Get file length. 3385 // 3386 fseek (pInFile, 0, SEEK_END); 3387 Length = ftell (pInFile); 3388 fseek (pInFile, 0, SEEK_SET); 3389 3390 // 3391 // Get file data. 3392 // 3393 StringPtr = new UINT8[Length]; 3394 if (StringPtr == NULL) { 3395 fclose (pInFile); 3396 return NULL; 3397 } 3398 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile); 3399 fclose (pInFile); 3400 3401 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr; 3402 // 3403 // Check the String package. 3404 // 3405 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) { 3406 delete[] StringPtr; 3407 return NULL; 3408 } 3409 3410 // 3411 // Search the language, get best language base on RFC 4647 matching algorithm. 3412 // 3413 Current = StringPtr; 3414 while (!GetBestLanguage ("en", PkgHeader->Language)) { 3415 Current += PkgHeader->Header.Length; 3416 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current; 3417 // 3418 // If can't find string package base on language, just return the first string package. 3419 // 3420 if (Current - StringPtr >= Length) { 3421 Current = StringPtr; 3422 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr; 3423 break; 3424 } 3425 } 3426 3427 Current += PkgHeader->HdrSize; 3428 // 3429 // Find the string block according the stringId. 3430 // 3431 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType); 3432 if (Status != EFI_SUCCESS) { 3433 delete[] StringPtr; 3434 return NULL; 3435 } 3436 3437 // 3438 // Get varstore name according the string type. 3439 // 3440 switch (BlockType) { 3441 case EFI_HII_SIBT_STRING_SCSU: 3442 case EFI_HII_SIBT_STRING_SCSU_FONT: 3443 case EFI_HII_SIBT_STRINGS_SCSU: 3444 case EFI_HII_SIBT_STRINGS_SCSU_FONT: 3445 StringName = (CHAR8*)(Current + NameOffset); 3446 VarStoreName = new CHAR8[strlen(StringName) + 1]; 3447 strcpy (VarStoreName, StringName); 3448 break; 3449 case EFI_HII_SIBT_STRING_UCS2: 3450 case EFI_HII_SIBT_STRING_UCS2_FONT: 3451 case EFI_HII_SIBT_STRINGS_UCS2: 3452 case EFI_HII_SIBT_STRINGS_UCS2_FONT: 3453 UnicodeString = (CHAR16*)(Current + NameOffset); 3454 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ; 3455 DestTmp = new CHAR8[Length / 2 + 1]; 3456 VarStoreName = DestTmp; 3457 while (*UnicodeString != '\0') { 3458 *(DestTmp++) = (CHAR8) *(UnicodeString++); 3459 } 3460 *DestTmp = '\0'; 3461 break; 3462 default: 3463 break; 3464 } 3465 3466 delete[] StringPtr; 3467 3468 return VarStoreName; 3469 } 3470 3471 EFI_STATUS 3472 CVfrStringDB::FindStringBlock ( 3473 IN UINT8 *StringData, 3474 IN EFI_STRING_ID StringId, 3475 OUT UINT32 *StringTextOffset, 3476 OUT UINT8 *BlockType 3477 ) 3478 { 3479 UINT8 *BlockHdr; 3480 EFI_STRING_ID CurrentStringId; 3481 UINT32 BlockSize; 3482 UINT32 Index; 3483 UINT8 *StringTextPtr; 3484 UINT32 Offset; 3485 UINT16 StringCount; 3486 UINT16 SkipCount; 3487 UINT8 Length8; 3488 EFI_HII_SIBT_EXT2_BLOCK Ext2; 3489 UINT32 Length32; 3490 UINT32 StringSize; 3491 3492 CurrentStringId = 1; 3493 3494 // 3495 // Parse the string blocks to get the string text and font. 3496 // 3497 BlockHdr = StringData; 3498 BlockSize = 0; 3499 Offset = 0; 3500 while (*BlockHdr != EFI_HII_SIBT_END) { 3501 switch (*BlockHdr) { 3502 case EFI_HII_SIBT_STRING_SCSU: 3503 Offset = sizeof (EFI_HII_STRING_BLOCK); 3504 StringTextPtr = BlockHdr + Offset; 3505 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1; 3506 CurrentStringId++; 3507 break; 3508 3509 case EFI_HII_SIBT_STRING_SCSU_FONT: 3510 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8); 3511 StringTextPtr = BlockHdr + Offset; 3512 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1; 3513 CurrentStringId++; 3514 break; 3515 3516 case EFI_HII_SIBT_STRINGS_SCSU: 3517 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3518 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8); 3519 BlockSize += StringTextPtr - BlockHdr; 3520 3521 for (Index = 0; Index < StringCount; Index++) { 3522 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1; 3523 if (CurrentStringId == StringId) { 3524 *BlockType = *BlockHdr; 3525 *StringTextOffset = StringTextPtr - StringData; 3526 return EFI_SUCCESS; 3527 } 3528 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1; 3529 CurrentStringId++; 3530 } 3531 break; 3532 3533 case EFI_HII_SIBT_STRINGS_SCSU_FONT: 3534 memcpy ( 3535 &StringCount, 3536 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3537 sizeof (UINT16) 3538 ); 3539 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8); 3540 BlockSize += StringTextPtr - BlockHdr; 3541 3542 for (Index = 0; Index < StringCount; Index++) { 3543 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1; 3544 if (CurrentStringId == StringId) { 3545 *BlockType = *BlockHdr; 3546 *StringTextOffset = StringTextPtr - StringData; 3547 return EFI_SUCCESS; 3548 } 3549 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1; 3550 CurrentStringId++; 3551 } 3552 break; 3553 3554 case EFI_HII_SIBT_STRING_UCS2: 3555 Offset = sizeof (EFI_HII_STRING_BLOCK); 3556 StringTextPtr = BlockHdr + Offset; 3557 // 3558 // Use StringSize to store the size of the specified string, including the NULL 3559 // terminator. 3560 // 3561 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3562 BlockSize += Offset + StringSize; 3563 CurrentStringId++; 3564 break; 3565 3566 case EFI_HII_SIBT_STRING_UCS2_FONT: 3567 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16); 3568 StringTextPtr = BlockHdr + Offset; 3569 // 3570 // Use StrSize to store the size of the specified string, including the NULL 3571 // terminator. 3572 // 3573 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3574 BlockSize += Offset + StringSize; 3575 CurrentStringId++; 3576 break; 3577 3578 case EFI_HII_SIBT_STRINGS_UCS2: 3579 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16); 3580 StringTextPtr = BlockHdr + Offset; 3581 BlockSize += Offset; 3582 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3583 for (Index = 0; Index < StringCount; Index++) { 3584 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3585 BlockSize += StringSize; 3586 if (CurrentStringId == StringId) { 3587 *BlockType = *BlockHdr; 3588 *StringTextOffset = StringTextPtr - StringData; 3589 return EFI_SUCCESS; 3590 } 3591 StringTextPtr = StringTextPtr + StringSize; 3592 CurrentStringId++; 3593 } 3594 break; 3595 3596 case EFI_HII_SIBT_STRINGS_UCS2_FONT: 3597 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16); 3598 StringTextPtr = BlockHdr + Offset; 3599 BlockSize += Offset; 3600 memcpy ( 3601 &StringCount, 3602 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3603 sizeof (UINT16) 3604 ); 3605 for (Index = 0; Index < StringCount; Index++) { 3606 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3607 BlockSize += StringSize; 3608 if (CurrentStringId == StringId) { 3609 *BlockType = *BlockHdr; 3610 *StringTextOffset = StringTextPtr - StringData; 3611 return EFI_SUCCESS; 3612 } 3613 StringTextPtr = StringTextPtr + StringSize; 3614 CurrentStringId++; 3615 } 3616 break; 3617 3618 case EFI_HII_SIBT_DUPLICATE: 3619 if (CurrentStringId == StringId) { 3620 // 3621 // Incoming StringId is an id of a duplicate string block. 3622 // Update the StringId to be the previous string block. 3623 // Go back to the header of string block to search. 3624 // 3625 memcpy ( 3626 &StringId, 3627 BlockHdr + sizeof (EFI_HII_STRING_BLOCK), 3628 sizeof (EFI_STRING_ID) 3629 ); 3630 CurrentStringId = 1; 3631 BlockSize = 0; 3632 } else { 3633 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK); 3634 CurrentStringId++; 3635 } 3636 break; 3637 3638 case EFI_HII_SIBT_SKIP1: 3639 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK))); 3640 CurrentStringId = (UINT16) (CurrentStringId + SkipCount); 3641 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK); 3642 break; 3643 3644 case EFI_HII_SIBT_SKIP2: 3645 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3646 CurrentStringId = (UINT16) (CurrentStringId + SkipCount); 3647 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); 3648 break; 3649 3650 case EFI_HII_SIBT_EXT1: 3651 memcpy ( 3652 &Length8, 3653 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3654 sizeof (UINT8) 3655 ); 3656 BlockSize += Length8; 3657 break; 3658 3659 case EFI_HII_SIBT_EXT2: 3660 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK)); 3661 BlockSize += Ext2.Length; 3662 break; 3663 3664 case EFI_HII_SIBT_EXT4: 3665 memcpy ( 3666 &Length32, 3667 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3668 sizeof (UINT32) 3669 ); 3670 3671 BlockSize += Length32; 3672 break; 3673 3674 default: 3675 break; 3676 } 3677 3678 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) { 3679 *StringTextOffset = BlockHdr - StringData + Offset; 3680 *BlockType = *BlockHdr; 3681 3682 if (StringId == CurrentStringId - 1) { 3683 // 3684 // if only one skip item, return EFI_NOT_FOUND. 3685 // 3686 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) { 3687 return EFI_NOT_FOUND; 3688 } else { 3689 return EFI_SUCCESS; 3690 } 3691 } 3692 3693 if (StringId < CurrentStringId - 1) { 3694 return EFI_NOT_FOUND; 3695 } 3696 } 3697 BlockHdr = StringData + BlockSize; 3698 } 3699 3700 return EFI_NOT_FOUND; 3701 } 3702 3703 UINT32 3704 CVfrStringDB::GetUnicodeStringTextSize ( 3705 IN UINT8 *StringSrc 3706 ) 3707 { 3708 UINT32 StringSize; 3709 CHAR16 *StringPtr; 3710 3711 StringSize = sizeof (CHAR16); 3712 StringPtr = (UINT16*)StringSrc; 3713 while (*StringPtr++ != L'\0') { 3714 StringSize += sizeof (CHAR16); 3715 } 3716 3717 return StringSize; 3718 } 3719 3720 BOOLEAN VfrCompatibleMode = FALSE; 3721 3722 CVfrVarDataTypeDB gCVfrVarDataTypeDB; 3723 CVfrDefaultStore gCVfrDefaultStore; 3724 CVfrDataStorage gCVfrDataStorage; 3725 3726 3727