1 /** @file 2 3 Vfr common library functions. 4 5 Copyright (c) 2004 - 2015, 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 BUFFER_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 BUFFER_SAFE_FREE (mName); 204 BUFFER_SAFE_FREE (mGuid); 205 BUFFER_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 (&Guid, 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 (&Guid, 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 } 1423 1424 CVfrDataStorage::~CVfrDataStorage ( 1425 VOID 1426 ) 1427 { 1428 SVfrVarStorageNode *pNode; 1429 1430 while (mBufferVarStoreList != NULL) { 1431 pNode = mBufferVarStoreList; 1432 mBufferVarStoreList = mBufferVarStoreList->mNext; 1433 delete pNode; 1434 } 1435 while (mEfiVarStoreList != NULL) { 1436 pNode = mEfiVarStoreList; 1437 mEfiVarStoreList = mEfiVarStoreList->mNext; 1438 delete pNode; 1439 } 1440 while (mNameVarStoreList != NULL) { 1441 pNode = mNameVarStoreList; 1442 mNameVarStoreList = mNameVarStoreList->mNext; 1443 delete pNode; 1444 } 1445 if (mNewVarStorageNode != NULL) { 1446 delete mNewVarStorageNode; 1447 } 1448 } 1449 1450 EFI_VARSTORE_ID 1451 CVfrDataStorage::GetFreeVarStoreId ( 1452 EFI_VFR_VARSTORE_TYPE VarType 1453 ) 1454 { 1455 UINT32 Index, Mask, Offset; 1456 1457 // 1458 // Assign the different ID range for the different type VarStore to support Framework Vfr 1459 // 1460 Index = 0; 1461 if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) { 1462 Index = 0; 1463 } else if (VarType == EFI_VFR_VARSTORE_EFI) { 1464 Index = 1; 1465 } else if (VarType == EFI_VFR_VARSTORE_NAME) { 1466 Index = 2; 1467 } 1468 1469 for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) { 1470 if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) { 1471 break; 1472 } 1473 } 1474 1475 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { 1476 if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) { 1477 mFreeVarStoreIdBitMap[Index] |= Mask; 1478 return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); 1479 } 1480 } 1481 1482 return EFI_VARSTORE_ID_INVALID; 1483 } 1484 1485 BOOLEAN 1486 CVfrDataStorage::ChekVarStoreIdFree ( 1487 IN EFI_VARSTORE_ID VarStoreId 1488 ) 1489 { 1490 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1491 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1492 1493 return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0; 1494 } 1495 1496 VOID 1497 CVfrDataStorage::MarkVarStoreIdUsed ( 1498 IN EFI_VARSTORE_ID VarStoreId 1499 ) 1500 { 1501 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1502 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1503 1504 mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset); 1505 } 1506 1507 VOID 1508 CVfrDataStorage::MarkVarStoreIdUnused ( 1509 IN EFI_VARSTORE_ID VarStoreId 1510 ) 1511 { 1512 UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32); 1513 UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32); 1514 1515 mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset); 1516 } 1517 1518 EFI_VFR_RETURN_CODE 1519 CVfrDataStorage::DeclareNameVarStoreBegin ( 1520 IN CHAR8 *StoreName, 1521 IN EFI_VARSTORE_ID VarStoreId 1522 ) 1523 { 1524 SVfrVarStorageNode *pNode = NULL; 1525 EFI_VARSTORE_ID TmpVarStoreId; 1526 1527 if (StoreName == NULL) { 1528 return VFR_RETURN_FATAL_ERROR; 1529 } 1530 1531 if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) { 1532 return VFR_RETURN_REDEFINED; 1533 } 1534 1535 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1536 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME); 1537 } else { 1538 if (ChekVarStoreIdFree (VarStoreId) == FALSE) { 1539 return VFR_RETURN_VARSTOREID_REDEFINED; 1540 } 1541 MarkVarStoreIdUsed (VarStoreId); 1542 } 1543 1544 if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) { 1545 return VFR_RETURN_UNDEFINED; 1546 } 1547 1548 mNewVarStorageNode = pNode; 1549 1550 return VFR_RETURN_SUCCESS; 1551 } 1552 1553 EFI_VFR_RETURN_CODE 1554 CVfrDataStorage::NameTableAddItem ( 1555 IN EFI_STRING_ID Item 1556 ) 1557 { 1558 EFI_VARSTORE_ID *NewTable, *OldTable; 1559 UINT32 TableSize; 1560 1561 OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable; 1562 TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize; 1563 1564 if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) { 1565 if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) { 1566 return VFR_RETURN_OUT_FOR_RESOURCES; 1567 } 1568 memcpy (NewTable, OldTable, TableSize); 1569 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable; 1570 } 1571 1572 mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item; 1573 mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize; 1574 1575 return VFR_RETURN_SUCCESS; 1576 } 1577 1578 EFI_VFR_RETURN_CODE 1579 CVfrDataStorage::DeclareNameVarStoreEnd ( 1580 IN EFI_GUID *Guid 1581 ) 1582 { 1583 mNewVarStorageNode->mGuid = *Guid; 1584 mNewVarStorageNode->mNext = mNameVarStoreList; 1585 mNameVarStoreList = mNewVarStorageNode; 1586 1587 mNewVarStorageNode = NULL; 1588 1589 return VFR_RETURN_SUCCESS; 1590 } 1591 1592 EFI_VFR_RETURN_CODE 1593 CVfrDataStorage::DeclareEfiVarStore ( 1594 IN CHAR8 *StoreName, 1595 IN EFI_GUID *Guid, 1596 IN EFI_STRING_ID NameStrId, 1597 IN UINT32 VarSize, 1598 IN BOOLEAN Flag 1599 ) 1600 { 1601 SVfrVarStorageNode *pNode; 1602 EFI_VARSTORE_ID VarStoreId; 1603 1604 if ((StoreName == NULL) || (Guid == NULL)) { 1605 return VFR_RETURN_FATAL_ERROR; 1606 } 1607 1608 if (VarSize > sizeof (UINT64)) { 1609 return VFR_RETURN_EFIVARSTORE_SIZE_ERROR; 1610 } 1611 1612 if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) { 1613 return VFR_RETURN_REDEFINED; 1614 } 1615 1616 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI); 1617 if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) { 1618 return VFR_RETURN_OUT_FOR_RESOURCES; 1619 } 1620 1621 pNode->mNext = mEfiVarStoreList; 1622 mEfiVarStoreList = pNode; 1623 1624 return VFR_RETURN_SUCCESS; 1625 } 1626 1627 EFI_VFR_RETURN_CODE 1628 CVfrDataStorage::DeclareBufferVarStore ( 1629 IN CHAR8 *StoreName, 1630 IN EFI_GUID *Guid, 1631 IN CVfrVarDataTypeDB *DataTypeDB, 1632 IN CHAR8 *TypeName, 1633 IN EFI_VARSTORE_ID VarStoreId, 1634 IN BOOLEAN Flag 1635 ) 1636 { 1637 SVfrVarStorageNode *pNew = NULL; 1638 SVfrDataType *pDataType = NULL; 1639 EFI_VARSTORE_ID TempVarStoreId; 1640 1641 if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) { 1642 return VFR_RETURN_FATAL_ERROR; 1643 } 1644 1645 if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) { 1646 return VFR_RETURN_REDEFINED; 1647 } 1648 1649 CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS); 1650 1651 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1652 VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER); 1653 } else { 1654 if (ChekVarStoreIdFree (VarStoreId) == FALSE) { 1655 return VFR_RETURN_VARSTOREID_REDEFINED; 1656 } 1657 MarkVarStoreIdUsed (VarStoreId); 1658 } 1659 1660 if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) { 1661 return VFR_RETURN_OUT_FOR_RESOURCES; 1662 } 1663 1664 pNew->mNext = mBufferVarStoreList; 1665 mBufferVarStoreList = pNew; 1666 1667 if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) { 1668 return VFR_RETURN_FATAL_ERROR; 1669 } 1670 1671 return VFR_RETURN_SUCCESS; 1672 } 1673 1674 EFI_VFR_RETURN_CODE 1675 CVfrDataStorage::GetVarStoreByDataType ( 1676 IN CHAR8 *DataTypeName, 1677 OUT SVfrVarStorageNode **VarNode, 1678 IN EFI_GUID *VarGuid 1679 ) 1680 { 1681 SVfrVarStorageNode *pNode; 1682 SVfrVarStorageNode *MatchNode; 1683 1684 // 1685 // Framework VFR uses Data type name as varstore name, so don't need check again. 1686 // 1687 if (VfrCompatibleMode) { 1688 return VFR_RETURN_UNDEFINED; 1689 } 1690 1691 MatchNode = NULL; 1692 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1693 if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) { 1694 continue; 1695 } 1696 1697 if ((VarGuid != NULL)) { 1698 if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) { 1699 *VarNode = pNode; 1700 return VFR_RETURN_SUCCESS; 1701 } 1702 } else { 1703 if (MatchNode == NULL) { 1704 MatchNode = pNode; 1705 } else { 1706 // 1707 // More than one varstores referred the same data structures. 1708 // 1709 return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR; 1710 } 1711 } 1712 } 1713 1714 if (MatchNode == NULL) { 1715 return VFR_RETURN_UNDEFINED; 1716 } 1717 1718 *VarNode = MatchNode; 1719 return VFR_RETURN_SUCCESS; 1720 } 1721 1722 EFI_VARSTORE_ID 1723 CVfrDataStorage::CheckGuidField ( 1724 IN SVfrVarStorageNode *pNode, 1725 IN EFI_GUID *StoreGuid, 1726 IN BOOLEAN *HasFoundOne, 1727 OUT EFI_VFR_RETURN_CODE *ReturnCode 1728 ) 1729 { 1730 if (StoreGuid != NULL) { 1731 // 1732 // If has guid info, compare the guid filed. 1733 // 1734 if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) { 1735 // 1736 // Both name and guid are same, this this varstore. 1737 // 1738 mCurrVarStorageNode = pNode; 1739 *ReturnCode = VFR_RETURN_SUCCESS; 1740 return TRUE; 1741 } 1742 } else { 1743 // 1744 // Not has Guid field, check whether this name is the only one. 1745 // 1746 if (*HasFoundOne) { 1747 // 1748 // The name has conflict, return name redefined. 1749 // 1750 *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR; 1751 return TRUE; 1752 } 1753 1754 *HasFoundOne = TRUE; 1755 mCurrVarStorageNode = pNode; 1756 } 1757 1758 return FALSE; 1759 } 1760 1761 /** 1762 Base on the input store name and guid to find the varstore id. 1763 1764 If both name and guid are inputed, base on the name and guid to 1765 found the varstore. If only name inputed, base on the name to 1766 found the varstore and go on to check whether more than one varstore 1767 has the same name. If only has found one varstore, return this 1768 varstore; if more than one varstore has same name, return varstore 1769 name redefined error. If no varstore found by varstore name, call 1770 function GetVarStoreByDataType and use inputed varstore name as 1771 data type name to search. 1772 **/ 1773 EFI_VFR_RETURN_CODE 1774 CVfrDataStorage::GetVarStoreId ( 1775 IN CHAR8 *StoreName, 1776 OUT EFI_VARSTORE_ID *VarStoreId, 1777 IN EFI_GUID *StoreGuid 1778 ) 1779 { 1780 EFI_VFR_RETURN_CODE ReturnCode; 1781 SVfrVarStorageNode *pNode; 1782 BOOLEAN HasFoundOne = FALSE; 1783 1784 mCurrVarStorageNode = NULL; 1785 1786 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1787 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1788 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1789 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1790 return ReturnCode; 1791 } 1792 } 1793 } 1794 1795 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1796 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1797 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1798 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1799 return ReturnCode; 1800 } 1801 } 1802 } 1803 1804 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1805 if (strcmp (pNode->mVarStoreName, StoreName) == 0) { 1806 if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) { 1807 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1808 return ReturnCode; 1809 } 1810 } 1811 } 1812 1813 if (HasFoundOne) { 1814 *VarStoreId = mCurrVarStorageNode->mVarStoreId; 1815 return VFR_RETURN_SUCCESS; 1816 } 1817 1818 *VarStoreId = EFI_VARSTORE_ID_INVALID; 1819 1820 // 1821 // Assume that Data strucutre name is used as StoreName, and check again. 1822 // 1823 ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid); 1824 if (pNode != NULL) { 1825 mCurrVarStorageNode = pNode; 1826 *VarStoreId = pNode->mVarStoreId; 1827 } 1828 1829 return ReturnCode; 1830 } 1831 1832 EFI_VFR_RETURN_CODE 1833 CVfrDataStorage::GetBufferVarStoreDataTypeName ( 1834 IN EFI_VARSTORE_ID VarStoreId, 1835 OUT CHAR8 **DataTypeName 1836 ) 1837 { 1838 SVfrVarStorageNode *pNode; 1839 1840 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1841 return VFR_RETURN_FATAL_ERROR; 1842 } 1843 1844 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1845 if (pNode->mVarStoreId == VarStoreId) { 1846 *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName; 1847 return VFR_RETURN_SUCCESS; 1848 } 1849 } 1850 1851 return VFR_RETURN_UNDEFINED; 1852 } 1853 1854 EFI_VFR_VARSTORE_TYPE 1855 CVfrDataStorage::GetVarStoreType ( 1856 IN EFI_VARSTORE_ID VarStoreId 1857 ) 1858 { 1859 SVfrVarStorageNode *pNode; 1860 EFI_VFR_VARSTORE_TYPE VarStoreType; 1861 1862 VarStoreType = EFI_VFR_VARSTORE_INVALID; 1863 1864 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1865 return VarStoreType; 1866 } 1867 1868 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1869 if (pNode->mVarStoreId == VarStoreId) { 1870 VarStoreType = pNode->mVarStoreType; 1871 return VarStoreType; 1872 } 1873 } 1874 1875 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1876 if (pNode->mVarStoreId == VarStoreId) { 1877 VarStoreType = pNode->mVarStoreType; 1878 return VarStoreType; 1879 } 1880 } 1881 1882 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1883 if (pNode->mVarStoreId == VarStoreId) { 1884 VarStoreType = pNode->mVarStoreType; 1885 return VarStoreType; 1886 } 1887 } 1888 1889 return VarStoreType; 1890 } 1891 1892 EFI_GUID * 1893 CVfrDataStorage::GetVarStoreGuid ( 1894 IN EFI_VARSTORE_ID VarStoreId 1895 ) 1896 { 1897 SVfrVarStorageNode *pNode; 1898 EFI_GUID *VarGuid; 1899 1900 VarGuid = NULL; 1901 1902 if (VarStoreId == EFI_VARSTORE_ID_INVALID) { 1903 return VarGuid; 1904 } 1905 1906 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1907 if (pNode->mVarStoreId == VarStoreId) { 1908 VarGuid = &pNode->mGuid; 1909 return VarGuid; 1910 } 1911 } 1912 1913 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1914 if (pNode->mVarStoreId == VarStoreId) { 1915 VarGuid = &pNode->mGuid; 1916 return VarGuid; 1917 } 1918 } 1919 1920 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1921 if (pNode->mVarStoreId == VarStoreId) { 1922 VarGuid = &pNode->mGuid; 1923 return VarGuid; 1924 } 1925 } 1926 1927 return VarGuid; 1928 } 1929 1930 EFI_VFR_RETURN_CODE 1931 CVfrDataStorage::GetVarStoreName ( 1932 IN EFI_VARSTORE_ID VarStoreId, 1933 OUT CHAR8 **VarStoreName 1934 ) 1935 { 1936 SVfrVarStorageNode *pNode; 1937 1938 if (VarStoreName == NULL) { 1939 return VFR_RETURN_FATAL_ERROR; 1940 } 1941 1942 for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1943 if (pNode->mVarStoreId == VarStoreId) { 1944 *VarStoreName = pNode->mVarStoreName; 1945 return VFR_RETURN_SUCCESS; 1946 } 1947 } 1948 1949 for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1950 if (pNode->mVarStoreId == VarStoreId) { 1951 *VarStoreName = pNode->mVarStoreName; 1952 return VFR_RETURN_SUCCESS; 1953 } 1954 } 1955 1956 for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { 1957 if (pNode->mVarStoreId == VarStoreId) { 1958 *VarStoreName = pNode->mVarStoreName; 1959 return VFR_RETURN_SUCCESS; 1960 } 1961 } 1962 1963 *VarStoreName = NULL; 1964 return VFR_RETURN_UNDEFINED; 1965 } 1966 1967 EFI_VFR_RETURN_CODE 1968 CVfrDataStorage::GetEfiVarStoreInfo ( 1969 IN OUT EFI_VARSTORE_INFO *Info 1970 ) 1971 { 1972 if (Info == NULL) { 1973 return VFR_RETURN_FATAL_ERROR; 1974 } 1975 1976 if (mCurrVarStorageNode == NULL) { 1977 return VFR_RETURN_GET_EFIVARSTORE_ERROR; 1978 } 1979 1980 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName; 1981 Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize; 1982 switch (Info->mVarTotalSize) { 1983 case 1: 1984 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8; 1985 break; 1986 case 2: 1987 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16; 1988 break; 1989 case 4: 1990 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32; 1991 break; 1992 case 8: 1993 Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64; 1994 break; 1995 default : 1996 return VFR_RETURN_FATAL_ERROR; 1997 } 1998 1999 return VFR_RETURN_SUCCESS; 2000 } 2001 2002 EFI_VFR_RETURN_CODE 2003 CVfrDataStorage::GetNameVarStoreInfo ( 2004 OUT EFI_VARSTORE_INFO *Info, 2005 IN UINT32 Index 2006 ) 2007 { 2008 if (Info == NULL) { 2009 return VFR_RETURN_FATAL_ERROR; 2010 } 2011 2012 if (mCurrVarStorageNode == NULL) { 2013 return VFR_RETURN_GET_NVVARSTORE_ERROR; 2014 } 2015 2016 // 2017 // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0. 2018 // 2019 if (VfrCompatibleMode) { 2020 if (Index == 0) { 2021 return VFR_RETURN_ERROR_ARRARY_NUM; 2022 } 2023 Index --; 2024 } 2025 2026 Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index]; 2027 2028 return VFR_RETURN_SUCCESS; 2029 } 2030 2031 SVfrDefaultStoreNode::SVfrDefaultStoreNode ( 2032 IN EFI_IFR_DEFAULTSTORE *ObjBinAddr, 2033 IN CHAR8 *RefName, 2034 IN EFI_STRING_ID DefaultStoreNameId, 2035 IN UINT16 DefaultId 2036 ) 2037 { 2038 mObjBinAddr = ObjBinAddr; 2039 2040 if (RefName != NULL) { 2041 mRefName = new CHAR8[strlen (RefName) + 1]; 2042 strcpy (mRefName, RefName); 2043 } else { 2044 mRefName = NULL; 2045 } 2046 2047 mNext = NULL; 2048 mDefaultId = DefaultId; 2049 mDefaultStoreNameId = DefaultStoreNameId; 2050 } 2051 2052 SVfrDefaultStoreNode::~SVfrDefaultStoreNode ( 2053 VOID 2054 ) 2055 { 2056 if (mRefName != NULL) { 2057 delete mRefName; 2058 } 2059 } 2060 2061 CVfrDefaultStore::CVfrDefaultStore ( 2062 VOID 2063 ) 2064 { 2065 mDefaultStoreList = NULL; 2066 } 2067 2068 CVfrDefaultStore::~CVfrDefaultStore ( 2069 VOID 2070 ) 2071 { 2072 SVfrDefaultStoreNode *pTmp = NULL; 2073 2074 while (mDefaultStoreList != NULL) { 2075 pTmp = mDefaultStoreList; 2076 mDefaultStoreList = mDefaultStoreList->mNext; 2077 delete pTmp; 2078 } 2079 } 2080 2081 EFI_VFR_RETURN_CODE 2082 CVfrDefaultStore::RegisterDefaultStore ( 2083 IN CHAR8 *ObjBinAddr, 2084 IN CHAR8 *RefName, 2085 IN EFI_STRING_ID DefaultStoreNameId, 2086 IN UINT16 DefaultId 2087 ) 2088 { 2089 SVfrDefaultStoreNode *pNode = NULL; 2090 2091 if (RefName == NULL) { 2092 return VFR_RETURN_FATAL_ERROR; 2093 } 2094 2095 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2096 if (strcmp (pNode->mRefName, RefName) == 0) { 2097 return VFR_RETURN_REDEFINED; 2098 } 2099 } 2100 2101 if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) { 2102 return VFR_RETURN_OUT_FOR_RESOURCES; 2103 } 2104 2105 pNode->mNext = mDefaultStoreList; 2106 mDefaultStoreList = pNode; 2107 2108 return VFR_RETURN_SUCCESS; 2109 } 2110 2111 /* 2112 * assign new reference name or new default store name id only if 2113 * the original is invalid 2114 */ 2115 EFI_VFR_RETURN_CODE 2116 CVfrDefaultStore::ReRegisterDefaultStoreById ( 2117 IN UINT16 DefaultId, 2118 IN CHAR8 *RefName, 2119 IN EFI_STRING_ID DefaultStoreNameId 2120 ) 2121 { 2122 SVfrDefaultStoreNode *pNode = NULL; 2123 2124 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2125 if (pNode->mDefaultId == DefaultId) { 2126 break; 2127 } 2128 } 2129 2130 if (pNode == NULL) { 2131 return VFR_RETURN_UNDEFINED; 2132 } else { 2133 if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) { 2134 pNode->mDefaultStoreNameId = DefaultStoreNameId; 2135 if (pNode->mObjBinAddr != NULL) { 2136 pNode->mObjBinAddr->DefaultName = DefaultStoreNameId; 2137 } 2138 } else { 2139 return VFR_RETURN_REDEFINED; 2140 } 2141 2142 if (RefName != NULL) { 2143 delete pNode->mRefName; 2144 pNode->mRefName = new CHAR8[strlen (RefName) + 1]; 2145 if (pNode->mRefName != NULL) { 2146 strcpy (pNode->mRefName, RefName); 2147 } 2148 } 2149 } 2150 2151 return VFR_RETURN_SUCCESS; 2152 } 2153 2154 BOOLEAN 2155 CVfrDefaultStore::DefaultIdRegistered ( 2156 IN UINT16 DefaultId 2157 ) 2158 { 2159 SVfrDefaultStoreNode *pNode = NULL; 2160 2161 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2162 if (pNode->mDefaultId == DefaultId) { 2163 return TRUE; 2164 } 2165 } 2166 2167 return FALSE; 2168 } 2169 2170 EFI_VFR_RETURN_CODE 2171 CVfrDefaultStore::GetDefaultId ( 2172 IN CHAR8 *RefName, 2173 OUT UINT16 *DefaultId 2174 ) 2175 { 2176 SVfrDefaultStoreNode *pTmp = NULL; 2177 2178 if (DefaultId == NULL) { 2179 return VFR_RETURN_FATAL_ERROR; 2180 } 2181 2182 for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) { 2183 if (strcmp (pTmp->mRefName, RefName) == 0) { 2184 *DefaultId = pTmp->mDefaultId; 2185 return VFR_RETURN_SUCCESS; 2186 } 2187 } 2188 2189 return VFR_RETURN_UNDEFINED; 2190 } 2191 2192 EFI_VFR_RETURN_CODE 2193 CVfrDefaultStore::BufferVarStoreAltConfigAdd ( 2194 IN EFI_VARSTORE_ID DefaultId, 2195 IN EFI_VARSTORE_INFO &Info, 2196 IN CHAR8 *VarStoreName, 2197 IN EFI_GUID *VarStoreGuid, 2198 IN UINT8 Type, 2199 IN EFI_IFR_TYPE_VALUE Value 2200 ) 2201 { 2202 SVfrDefaultStoreNode *pNode = NULL; 2203 CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,}; 2204 INTN Returnvalue = 0; 2205 2206 if (VarStoreName == NULL) { 2207 return VFR_RETURN_FATAL_ERROR; 2208 } 2209 2210 for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) { 2211 if (pNode->mDefaultId == DefaultId) { 2212 break; 2213 } 2214 } 2215 2216 if (pNode == NULL) { 2217 return VFR_RETURN_UNDEFINED; 2218 } 2219 2220 gCVfrBufferConfig.Open (); 2221 2222 sprintf (NewAltCfg, "%04x", pNode->mDefaultId); 2223 if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) { 2224 if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) { 2225 goto WriteError; 2226 } 2227 } 2228 2229 gCVfrBufferConfig.Close (); 2230 2231 return VFR_RETURN_SUCCESS; 2232 2233 WriteError: 2234 gCVfrBufferConfig.Close (); 2235 return (EFI_VFR_RETURN_CODE)Returnvalue; 2236 } 2237 2238 SVfrRuleNode::SVfrRuleNode ( 2239 IN CHAR8 *RuleName, 2240 IN UINT8 RuleId 2241 ) 2242 { 2243 if (RuleName != NULL) { 2244 mRuleName = new CHAR8[strlen (RuleName) + 1]; 2245 strcpy (mRuleName, RuleName); 2246 } else { 2247 mRuleName = NULL; 2248 } 2249 2250 mNext = NULL; 2251 mRuleId = RuleId; 2252 } 2253 2254 SVfrRuleNode::~SVfrRuleNode ( 2255 VOID 2256 ) 2257 { 2258 if (mRuleName != NULL) { 2259 delete mRuleName; 2260 } 2261 } 2262 2263 CVfrRulesDB::CVfrRulesDB () 2264 { 2265 mRuleList = NULL; 2266 mFreeRuleId = EFI_VARSTORE_ID_START; 2267 } 2268 2269 CVfrRulesDB::~CVfrRulesDB () 2270 { 2271 SVfrRuleNode *pNode; 2272 2273 while(mRuleList != NULL) { 2274 pNode = mRuleList; 2275 mRuleList = mRuleList->mNext; 2276 delete pNode; 2277 } 2278 } 2279 2280 VOID 2281 CVfrRulesDB::RegisterRule ( 2282 IN CHAR8 *RuleName 2283 ) 2284 { 2285 SVfrRuleNode *pNew; 2286 2287 if (RuleName == NULL) { 2288 return ; 2289 } 2290 2291 if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) { 2292 return ; 2293 } 2294 2295 mFreeRuleId++; 2296 2297 pNew->mNext = mRuleList; 2298 mRuleList = pNew; 2299 } 2300 2301 UINT8 2302 CVfrRulesDB::GetRuleId ( 2303 IN CHAR8 *RuleName 2304 ) 2305 { 2306 SVfrRuleNode *pNode; 2307 2308 if (RuleName == NULL) { 2309 return EFI_RULE_ID_INVALID; 2310 } 2311 2312 for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) { 2313 if (strcmp (pNode->mRuleName, RuleName) == 0) { 2314 return pNode->mRuleId; 2315 } 2316 } 2317 2318 return EFI_RULE_ID_INVALID; 2319 } 2320 2321 CVfrRulesDB gCVfrRulesDB; 2322 2323 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( 2324 VOID 2325 ) 2326 { 2327 mVarStoreId = EFI_VARSTORE_ID_INVALID; 2328 mInfo.mVarName = EFI_STRING_ID_INVALID; 2329 mInfo.mVarOffset = EFI_VAROFFSET_INVALID; 2330 mVarType = EFI_IFR_TYPE_OTHER; 2331 mVarTotalSize = 0; 2332 } 2333 2334 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( 2335 IN EFI_VARSTORE_INFO &Info 2336 ) 2337 { 2338 mVarStoreId = Info.mVarStoreId; 2339 mInfo.mVarName = Info.mInfo.mVarName; 2340 mInfo.mVarOffset = Info.mInfo.mVarOffset; 2341 mVarType = Info.mVarType; 2342 mVarTotalSize = Info.mVarTotalSize; 2343 } 2344 2345 BOOLEAN 2346 EFI_VARSTORE_INFO::operator == ( 2347 IN EFI_VARSTORE_INFO *Info 2348 ) 2349 { 2350 if ((mVarStoreId == Info->mVarStoreId) && 2351 (mInfo.mVarName == Info->mInfo.mVarName) && 2352 (mInfo.mVarOffset == Info->mInfo.mVarOffset) && 2353 (mVarType == Info->mVarType) && 2354 (mVarTotalSize == Info->mVarTotalSize)) { 2355 return TRUE; 2356 } 2357 2358 return FALSE; 2359 } 2360 2361 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo; 2362 2363 EFI_QUESTION_ID 2364 CVfrQuestionDB::GetFreeQuestionId ( 2365 VOID 2366 ) 2367 { 2368 UINT32 Index, Mask, Offset; 2369 2370 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2371 if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) { 2372 break; 2373 } 2374 } 2375 2376 for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { 2377 if ((mFreeQIdBitMap[Index] & Mask) == 0) { 2378 mFreeQIdBitMap[Index] |= Mask; 2379 return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset); 2380 } 2381 } 2382 2383 return EFI_QUESTION_ID_INVALID; 2384 } 2385 2386 BOOLEAN 2387 CVfrQuestionDB::ChekQuestionIdFree ( 2388 IN EFI_QUESTION_ID QId 2389 ) 2390 { 2391 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2392 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2393 2394 return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0; 2395 } 2396 2397 VOID 2398 CVfrQuestionDB::MarkQuestionIdUsed ( 2399 IN EFI_QUESTION_ID QId 2400 ) 2401 { 2402 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2403 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2404 2405 mFreeQIdBitMap[Index] |= (0x80000000 >> Offset); 2406 } 2407 2408 VOID 2409 CVfrQuestionDB::MarkQuestionIdUnused ( 2410 IN EFI_QUESTION_ID QId 2411 ) 2412 { 2413 UINT32 Index = (QId / EFI_BITS_PER_UINT32); 2414 UINT32 Offset = (QId % EFI_BITS_PER_UINT32); 2415 2416 mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset); 2417 } 2418 2419 SVfrQuestionNode::SVfrQuestionNode ( 2420 IN CHAR8 *Name, 2421 IN CHAR8 *VarIdStr, 2422 IN UINT32 BitMask 2423 ) 2424 { 2425 mName = NULL; 2426 mVarIdStr = NULL; 2427 mQuestionId = EFI_QUESTION_ID_INVALID; 2428 mBitMask = BitMask; 2429 mNext = NULL; 2430 mQtype = QUESTION_NORMAL; 2431 2432 if (Name == NULL) { 2433 mName = new CHAR8[strlen ("$DEFAULT") + 1]; 2434 strcpy (mName, "$DEFAULT"); 2435 } else { 2436 mName = new CHAR8[strlen (Name) + 1]; 2437 strcpy (mName, Name); 2438 } 2439 2440 if (VarIdStr != NULL) { 2441 mVarIdStr = new CHAR8[strlen (VarIdStr) + 1]; 2442 strcpy (mVarIdStr, VarIdStr); 2443 } else { 2444 mVarIdStr = new CHAR8[strlen ("$") + 1]; 2445 strcpy (mVarIdStr, "$"); 2446 } 2447 } 2448 2449 SVfrQuestionNode::~SVfrQuestionNode ( 2450 VOID 2451 ) 2452 { 2453 if (mName != NULL) { 2454 delete mName; 2455 } 2456 2457 if (mVarIdStr != NULL) { 2458 delete mVarIdStr; 2459 } 2460 } 2461 2462 CVfrQuestionDB::CVfrQuestionDB () 2463 { 2464 UINT32 Index; 2465 2466 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2467 mFreeQIdBitMap[Index] = 0; 2468 } 2469 2470 // Question ID 0 is reserved. 2471 mFreeQIdBitMap[0] = 0x80000000; 2472 mQuestionList = NULL; 2473 } 2474 2475 CVfrQuestionDB::~CVfrQuestionDB () 2476 { 2477 SVfrQuestionNode *pNode; 2478 2479 while (mQuestionList != NULL) { 2480 pNode = mQuestionList; 2481 mQuestionList = mQuestionList->mNext; 2482 delete pNode; 2483 } 2484 } 2485 2486 // 2487 // Reset to init state 2488 // 2489 VOID 2490 CVfrQuestionDB::ResetInit( 2491 IN VOID 2492 ) 2493 { 2494 UINT32 Index; 2495 SVfrQuestionNode *pNode; 2496 2497 while (mQuestionList != NULL) { 2498 pNode = mQuestionList; 2499 mQuestionList = mQuestionList->mNext; 2500 delete pNode; 2501 } 2502 2503 for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) { 2504 mFreeQIdBitMap[Index] = 0; 2505 } 2506 2507 // Question ID 0 is reserved. 2508 mFreeQIdBitMap[0] = 0x80000000; 2509 mQuestionList = NULL; 2510 } 2511 2512 VOID 2513 CVfrQuestionDB::PrintAllQuestion ( 2514 VOID 2515 ) 2516 { 2517 SVfrQuestionNode *pNode = NULL; 2518 2519 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 2520 printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId); 2521 } 2522 } 2523 2524 EFI_VFR_RETURN_CODE 2525 CVfrQuestionDB::RegisterQuestion ( 2526 IN CHAR8 *Name, 2527 IN CHAR8 *VarIdStr, 2528 IN OUT EFI_QUESTION_ID &QuestionId 2529 ) 2530 { 2531 SVfrQuestionNode *pNode = NULL; 2532 2533 if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) { 2534 return VFR_RETURN_REDEFINED; 2535 } 2536 2537 if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) { 2538 return VFR_RETURN_OUT_FOR_RESOURCES; 2539 } 2540 2541 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2542 QuestionId = GetFreeQuestionId (); 2543 } else { 2544 // 2545 // For Framework Vfr, don't check question ID conflict. 2546 // 2547 if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) { 2548 delete pNode; 2549 return VFR_RETURN_QUESTIONID_REDEFINED; 2550 } 2551 MarkQuestionIdUsed (QuestionId); 2552 } 2553 pNode->mQuestionId = QuestionId; 2554 2555 pNode->mNext = mQuestionList; 2556 mQuestionList = pNode; 2557 2558 gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2559 2560 return VFR_RETURN_SUCCESS; 2561 } 2562 2563 VOID 2564 CVfrQuestionDB::RegisterOldDateQuestion ( 2565 IN CHAR8 *YearVarId, 2566 IN CHAR8 *MonthVarId, 2567 IN CHAR8 *DayVarId, 2568 IN OUT EFI_QUESTION_ID &QuestionId 2569 ) 2570 { 2571 SVfrQuestionNode *pNode[3] = {NULL, }; 2572 UINT32 Index; 2573 2574 if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) { 2575 return; 2576 } 2577 2578 if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) { 2579 goto Err; 2580 } 2581 if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) { 2582 goto Err; 2583 } 2584 if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) { 2585 goto Err; 2586 } 2587 2588 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2589 QuestionId = GetFreeQuestionId (); 2590 } else { 2591 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2592 goto Err; 2593 } 2594 MarkQuestionIdUsed (QuestionId); 2595 } 2596 2597 pNode[0]->mQuestionId = QuestionId; 2598 pNode[1]->mQuestionId = QuestionId; 2599 pNode[2]->mQuestionId = QuestionId; 2600 pNode[0]->mQtype = QUESTION_DATE; 2601 pNode[1]->mQtype = QUESTION_DATE; 2602 pNode[2]->mQtype = QUESTION_DATE; 2603 pNode[0]->mNext = pNode[1]; 2604 pNode[1]->mNext = pNode[2]; 2605 pNode[2]->mNext = mQuestionList; 2606 mQuestionList = pNode[0]; 2607 2608 gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2609 gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2610 gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2611 2612 return; 2613 2614 Err: 2615 for (Index = 0; Index < 3; Index++) { 2616 if (pNode[Index] != NULL) { 2617 delete pNode[Index]; 2618 } 2619 } 2620 QuestionId = EFI_QUESTION_ID_INVALID; 2621 } 2622 2623 VOID 2624 CVfrQuestionDB::RegisterNewDateQuestion ( 2625 IN CHAR8 *Name, 2626 IN CHAR8 *BaseVarId, 2627 IN OUT EFI_QUESTION_ID &QuestionId 2628 ) 2629 { 2630 SVfrQuestionNode *pNode[3] = {NULL, }; 2631 UINT32 Len; 2632 CHAR8 *VarIdStr[3] = {NULL, }; 2633 CHAR8 Index; 2634 2635 if (BaseVarId == NULL && Name == NULL) { 2636 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2637 QuestionId = GetFreeQuestionId (); 2638 } else { 2639 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2640 goto Err; 2641 } 2642 MarkQuestionIdUsed (QuestionId); 2643 } 2644 return; 2645 } 2646 2647 if (BaseVarId != NULL) { 2648 Len = strlen (BaseVarId); 2649 2650 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1]; 2651 if (VarIdStr[0] != NULL) { 2652 strcpy (VarIdStr[0], BaseVarId); 2653 strcat (VarIdStr[0], ".Year"); 2654 } 2655 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1]; 2656 if (VarIdStr[1] != NULL) { 2657 strcpy (VarIdStr[1], BaseVarId); 2658 strcat (VarIdStr[1], ".Month"); 2659 } 2660 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1]; 2661 if (VarIdStr[2] != NULL) { 2662 strcpy (VarIdStr[2], BaseVarId); 2663 strcat (VarIdStr[2], ".Day"); 2664 } 2665 } else { 2666 Len = strlen (Name); 2667 2668 VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1]; 2669 if (VarIdStr[0] != NULL) { 2670 strcpy (VarIdStr[0], Name); 2671 strcat (VarIdStr[0], ".Year"); 2672 } 2673 VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1]; 2674 if (VarIdStr[1] != NULL) { 2675 strcpy (VarIdStr[1], Name); 2676 strcat (VarIdStr[1], ".Month"); 2677 } 2678 VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1]; 2679 if (VarIdStr[2] != NULL) { 2680 strcpy (VarIdStr[2], Name); 2681 strcat (VarIdStr[2], ".Day"); 2682 } 2683 } 2684 2685 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) { 2686 goto Err; 2687 } 2688 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) { 2689 goto Err; 2690 } 2691 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) { 2692 goto Err; 2693 } 2694 2695 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2696 QuestionId = GetFreeQuestionId (); 2697 } else { 2698 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2699 goto Err; 2700 } 2701 MarkQuestionIdUsed (QuestionId); 2702 } 2703 2704 pNode[0]->mQuestionId = QuestionId; 2705 pNode[1]->mQuestionId = QuestionId; 2706 pNode[2]->mQuestionId = QuestionId; 2707 pNode[0]->mQtype = QUESTION_DATE; 2708 pNode[1]->mQtype = QUESTION_DATE; 2709 pNode[2]->mQtype = QUESTION_DATE; 2710 pNode[0]->mNext = pNode[1]; 2711 pNode[1]->mNext = pNode[2]; 2712 pNode[2]->mNext = mQuestionList; 2713 mQuestionList = pNode[0]; 2714 2715 for (Index = 0; Index < 3; Index++) { 2716 if (VarIdStr[Index] != NULL) { 2717 delete VarIdStr[Index]; 2718 } 2719 } 2720 2721 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2722 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2723 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2724 2725 return; 2726 2727 Err: 2728 for (Index = 0; Index < 3; Index++) { 2729 if (pNode[Index] != NULL) { 2730 delete pNode[Index]; 2731 } 2732 2733 if (VarIdStr[Index] != NULL) { 2734 delete VarIdStr[Index]; 2735 } 2736 } 2737 } 2738 2739 VOID 2740 CVfrQuestionDB::RegisterOldTimeQuestion ( 2741 IN CHAR8 *HourVarId, 2742 IN CHAR8 *MinuteVarId, 2743 IN CHAR8 *SecondVarId, 2744 IN OUT EFI_QUESTION_ID &QuestionId 2745 ) 2746 { 2747 SVfrQuestionNode *pNode[3] = {NULL, }; 2748 UINT32 Index; 2749 2750 if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) { 2751 return; 2752 } 2753 2754 if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) { 2755 goto Err; 2756 } 2757 if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) { 2758 goto Err; 2759 } 2760 if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) { 2761 goto Err; 2762 } 2763 2764 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2765 QuestionId = GetFreeQuestionId (); 2766 } else { 2767 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2768 goto Err; 2769 } 2770 MarkQuestionIdUsed (QuestionId); 2771 } 2772 2773 pNode[0]->mQuestionId = QuestionId; 2774 pNode[1]->mQuestionId = QuestionId; 2775 pNode[2]->mQuestionId = QuestionId; 2776 pNode[0]->mQtype = QUESTION_TIME; 2777 pNode[1]->mQtype = QUESTION_TIME; 2778 pNode[2]->mQtype = QUESTION_TIME; 2779 pNode[0]->mNext = pNode[1]; 2780 pNode[1]->mNext = pNode[2]; 2781 pNode[2]->mNext = mQuestionList; 2782 mQuestionList = pNode[0]; 2783 2784 gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2785 gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2786 gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2787 2788 return; 2789 2790 Err: 2791 for (Index = 0; Index < 3; Index++) { 2792 if (pNode[Index] != NULL) { 2793 delete pNode[Index]; 2794 } 2795 } 2796 QuestionId = EFI_QUESTION_ID_INVALID; 2797 } 2798 2799 VOID 2800 CVfrQuestionDB::RegisterNewTimeQuestion ( 2801 IN CHAR8 *Name, 2802 IN CHAR8 *BaseVarId, 2803 IN OUT EFI_QUESTION_ID &QuestionId 2804 ) 2805 { 2806 SVfrQuestionNode *pNode[3] = {NULL, }; 2807 UINT32 Len; 2808 CHAR8 *VarIdStr[3] = {NULL, }; 2809 CHAR8 Index; 2810 2811 if (BaseVarId == NULL && Name == NULL) { 2812 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2813 QuestionId = GetFreeQuestionId (); 2814 } else { 2815 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2816 goto Err; 2817 } 2818 MarkQuestionIdUsed (QuestionId); 2819 } 2820 return; 2821 } 2822 2823 if (BaseVarId != NULL) { 2824 Len = strlen (BaseVarId); 2825 2826 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1]; 2827 if (VarIdStr[0] != NULL) { 2828 strcpy (VarIdStr[0], BaseVarId); 2829 strcat (VarIdStr[0], ".Hour"); 2830 } 2831 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1]; 2832 if (VarIdStr[1] != NULL) { 2833 strcpy (VarIdStr[1], BaseVarId); 2834 strcat (VarIdStr[1], ".Minute"); 2835 } 2836 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1]; 2837 if (VarIdStr[2] != NULL) { 2838 strcpy (VarIdStr[2], BaseVarId); 2839 strcat (VarIdStr[2], ".Second"); 2840 } 2841 } else { 2842 Len = strlen (Name); 2843 2844 VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1]; 2845 if (VarIdStr[0] != NULL) { 2846 strcpy (VarIdStr[0], Name); 2847 strcat (VarIdStr[0], ".Hour"); 2848 } 2849 VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1]; 2850 if (VarIdStr[1] != NULL) { 2851 strcpy (VarIdStr[1], Name); 2852 strcat (VarIdStr[1], ".Minute"); 2853 } 2854 VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1]; 2855 if (VarIdStr[2] != NULL) { 2856 strcpy (VarIdStr[2], Name); 2857 strcat (VarIdStr[2], ".Second"); 2858 } 2859 } 2860 2861 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) { 2862 goto Err; 2863 } 2864 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) { 2865 goto Err; 2866 } 2867 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) { 2868 goto Err; 2869 } 2870 2871 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2872 QuestionId = GetFreeQuestionId (); 2873 } else { 2874 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2875 goto Err; 2876 } 2877 MarkQuestionIdUsed (QuestionId); 2878 } 2879 2880 pNode[0]->mQuestionId = QuestionId; 2881 pNode[1]->mQuestionId = QuestionId; 2882 pNode[2]->mQuestionId = QuestionId; 2883 pNode[0]->mQtype = QUESTION_TIME; 2884 pNode[1]->mQtype = QUESTION_TIME; 2885 pNode[2]->mQtype = QUESTION_TIME; 2886 pNode[0]->mNext = pNode[1]; 2887 pNode[1]->mNext = pNode[2]; 2888 pNode[2]->mNext = mQuestionList; 2889 mQuestionList = pNode[0]; 2890 2891 for (Index = 0; Index < 3; Index++) { 2892 if (VarIdStr[Index] != NULL) { 2893 delete VarIdStr[Index]; 2894 } 2895 } 2896 2897 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2898 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2899 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 2900 2901 return; 2902 2903 Err: 2904 for (Index = 0; Index < 3; Index++) { 2905 if (pNode[Index] != NULL) { 2906 delete pNode[Index]; 2907 } 2908 2909 if (VarIdStr[Index] != NULL) { 2910 delete VarIdStr[Index]; 2911 } 2912 } 2913 } 2914 2915 VOID 2916 CVfrQuestionDB::RegisterRefQuestion ( 2917 IN CHAR8 *Name, 2918 IN CHAR8 *BaseVarId, 2919 IN OUT EFI_QUESTION_ID &QuestionId 2920 ) 2921 { 2922 SVfrQuestionNode *pNode[4] = {NULL, }; 2923 UINT32 Len; 2924 CHAR8 *VarIdStr[4] = {NULL, }; 2925 CHAR8 Index; 2926 2927 if (BaseVarId == NULL && Name == NULL) { 2928 return; 2929 } 2930 2931 if (BaseVarId != NULL) { 2932 Len = strlen (BaseVarId); 2933 2934 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1]; 2935 if (VarIdStr[0] != NULL) { 2936 strcpy (VarIdStr[0], BaseVarId); 2937 strcat (VarIdStr[0], ".QuestionId"); 2938 } 2939 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1]; 2940 if (VarIdStr[1] != NULL) { 2941 strcpy (VarIdStr[1], BaseVarId); 2942 strcat (VarIdStr[1], ".FormId"); 2943 } 2944 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1]; 2945 if (VarIdStr[2] != NULL) { 2946 strcpy (VarIdStr[2], BaseVarId); 2947 strcat (VarIdStr[2], ".FormSetGuid"); 2948 } 2949 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1]; 2950 if (VarIdStr[3] != NULL) { 2951 strcpy (VarIdStr[3], BaseVarId); 2952 strcat (VarIdStr[3], ".DevicePath"); 2953 } 2954 } else { 2955 Len = strlen (Name); 2956 2957 VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1]; 2958 if (VarIdStr[0] != NULL) { 2959 strcpy (VarIdStr[0], Name); 2960 strcat (VarIdStr[0], ".QuestionId"); 2961 } 2962 VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1]; 2963 if (VarIdStr[1] != NULL) { 2964 strcpy (VarIdStr[1], Name); 2965 strcat (VarIdStr[1], ".FormId"); 2966 } 2967 VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1]; 2968 if (VarIdStr[2] != NULL) { 2969 strcpy (VarIdStr[2], Name); 2970 strcat (VarIdStr[2], ".FormSetGuid"); 2971 } 2972 VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1]; 2973 if (VarIdStr[3] != NULL) { 2974 strcpy (VarIdStr[3], Name); 2975 strcat (VarIdStr[3], ".DevicePath"); 2976 } 2977 } 2978 2979 if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) { 2980 goto Err; 2981 } 2982 if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) { 2983 goto Err; 2984 } 2985 if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) { 2986 goto Err; 2987 } 2988 if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) { 2989 goto Err; 2990 } 2991 2992 if (QuestionId == EFI_QUESTION_ID_INVALID) { 2993 QuestionId = GetFreeQuestionId (); 2994 } else { 2995 if (ChekQuestionIdFree (QuestionId) == FALSE) { 2996 goto Err; 2997 } 2998 MarkQuestionIdUsed (QuestionId); 2999 } 3000 3001 pNode[0]->mQuestionId = QuestionId; 3002 pNode[1]->mQuestionId = QuestionId; 3003 pNode[2]->mQuestionId = QuestionId; 3004 pNode[3]->mQuestionId = QuestionId; 3005 pNode[0]->mQtype = QUESTION_REF; 3006 pNode[1]->mQtype = QUESTION_REF; 3007 pNode[2]->mQtype = QUESTION_REF; 3008 pNode[3]->mQtype = QUESTION_REF; 3009 pNode[0]->mNext = pNode[1]; 3010 pNode[1]->mNext = pNode[2]; 3011 pNode[2]->mNext = pNode[3]; 3012 pNode[3]->mNext = mQuestionList; 3013 mQuestionList = pNode[0]; 3014 3015 gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3016 gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3017 gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3018 gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); 3019 3020 return; 3021 3022 Err: 3023 for (Index = 0; Index < 4; Index++) { 3024 if (pNode[Index] != NULL) { 3025 delete pNode[Index]; 3026 } 3027 3028 if (VarIdStr[Index] != NULL) { 3029 delete VarIdStr[Index]; 3030 } 3031 } 3032 } 3033 3034 EFI_VFR_RETURN_CODE 3035 CVfrQuestionDB::UpdateQuestionId ( 3036 IN EFI_QUESTION_ID QId, 3037 IN EFI_QUESTION_ID NewQId 3038 ) 3039 { 3040 SVfrQuestionNode *pNode = NULL; 3041 3042 if (QId == NewQId) { 3043 // don't update 3044 return VFR_RETURN_SUCCESS; 3045 } 3046 3047 // 3048 // For Framework Vfr, don't check question ID conflict. 3049 // 3050 if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) { 3051 return VFR_RETURN_REDEFINED; 3052 } 3053 3054 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3055 if (pNode->mQuestionId == QId) { 3056 break; 3057 } 3058 } 3059 3060 if (pNode == NULL) { 3061 return VFR_RETURN_UNDEFINED; 3062 } 3063 3064 MarkQuestionIdUnused (QId); 3065 pNode->mQuestionId = NewQId; 3066 MarkQuestionIdUsed (NewQId); 3067 3068 gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID)); 3069 3070 return VFR_RETURN_SUCCESS; 3071 } 3072 3073 VOID 3074 CVfrQuestionDB::GetQuestionId ( 3075 IN CHAR8 *Name, 3076 IN CHAR8 *VarIdStr, 3077 OUT EFI_QUESTION_ID &QuestionId, 3078 OUT UINT32 &BitMask, 3079 OUT EFI_QUESION_TYPE *QType 3080 ) 3081 { 3082 SVfrQuestionNode *pNode; 3083 3084 QuestionId = EFI_QUESTION_ID_INVALID; 3085 BitMask = 0x00000000; 3086 if (QType != NULL) { 3087 *QType = QUESTION_NORMAL; 3088 } 3089 3090 if ((Name == NULL) && (VarIdStr == NULL)) { 3091 return ; 3092 } 3093 3094 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3095 if (Name != NULL) { 3096 if (strcmp (pNode->mName, Name) != 0) { 3097 continue; 3098 } 3099 } 3100 3101 if (VarIdStr != NULL) { 3102 if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) { 3103 continue; 3104 } 3105 } 3106 3107 QuestionId = pNode->mQuestionId; 3108 BitMask = pNode->mBitMask; 3109 if (QType != NULL) { 3110 *QType = pNode->mQtype; 3111 } 3112 break; 3113 } 3114 3115 return ; 3116 } 3117 3118 EFI_VFR_RETURN_CODE 3119 CVfrQuestionDB::FindQuestion ( 3120 IN EFI_QUESTION_ID QuestionId 3121 ) 3122 { 3123 SVfrQuestionNode *pNode; 3124 3125 if (QuestionId == EFI_QUESTION_ID_INVALID) { 3126 return VFR_RETURN_INVALID_PARAMETER; 3127 } 3128 3129 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3130 if (pNode->mQuestionId == QuestionId) { 3131 return VFR_RETURN_SUCCESS; 3132 } 3133 } 3134 3135 return VFR_RETURN_UNDEFINED; 3136 } 3137 3138 EFI_VFR_RETURN_CODE 3139 CVfrQuestionDB::FindQuestion ( 3140 IN CHAR8 *Name 3141 ) 3142 { 3143 SVfrQuestionNode *pNode; 3144 3145 if (Name == NULL) { 3146 return VFR_RETURN_FATAL_ERROR; 3147 } 3148 3149 for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { 3150 if (strcmp (pNode->mName, Name) == 0) { 3151 return VFR_RETURN_SUCCESS; 3152 } 3153 } 3154 3155 return VFR_RETURN_UNDEFINED; 3156 } 3157 3158 CVfrStringDB::CVfrStringDB () 3159 { 3160 mStringFileName = NULL; 3161 } 3162 3163 CVfrStringDB::~CVfrStringDB () 3164 { 3165 if (mStringFileName != NULL) { 3166 delete mStringFileName; 3167 } 3168 mStringFileName = NULL; 3169 } 3170 3171 3172 VOID 3173 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName) 3174 { 3175 UINT32 FileLen = 0; 3176 3177 if (StringFileName == NULL) { 3178 return; 3179 } 3180 3181 FileLen = strlen (StringFileName) + 1; 3182 mStringFileName = new CHAR8[FileLen]; 3183 if (mStringFileName == NULL) { 3184 return; 3185 } 3186 3187 strcpy (mStringFileName, StringFileName); 3188 mStringFileName[FileLen - 1] = '\0'; 3189 } 3190 3191 3192 /** 3193 Returns TRUE or FALSE whether SupportedLanguages contains the best matching language 3194 from a set of supported languages. 3195 3196 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that 3197 contains a set of language codes. 3198 @param[in] Language A variable that contains pointers to Null-terminated 3199 ASCII strings that contain one language codes. 3200 3201 @retval FALSE The best matching language could not be found in SupportedLanguages. 3202 @retval TRUE The best matching language could be found in SupportedLanguages. 3203 3204 **/ 3205 BOOLEAN 3206 CVfrStringDB::GetBestLanguage ( 3207 IN CONST CHAR8 *SupportedLanguages, 3208 IN CHAR8 *Language 3209 ) 3210 { 3211 UINTN CompareLength; 3212 UINTN LanguageLength; 3213 CONST CHAR8 *Supported; 3214 3215 if (SupportedLanguages == NULL || Language == NULL){ 3216 return FALSE; 3217 } 3218 3219 // 3220 // Determine the length of the first RFC 4646 language code in Language 3221 // 3222 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++); 3223 3224 // 3225 // Trim back the length of Language used until it is empty 3226 // 3227 while (LanguageLength > 0) { 3228 // 3229 // Loop through all language codes in SupportedLanguages 3230 // 3231 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) { 3232 // 3233 // Skip ';' characters in Supported 3234 // 3235 for (; *Supported != '\0' && *Supported == ';'; Supported++); 3236 // 3237 // Determine the length of the next language code in Supported 3238 // 3239 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++); 3240 // 3241 // If Language is longer than the Supported, then skip to the next language 3242 // 3243 if (LanguageLength > CompareLength) { 3244 continue; 3245 } 3246 3247 // 3248 // See if the first LanguageLength characters in Supported match Language 3249 // 3250 if (strncmp (Supported, Language, LanguageLength) == 0) { 3251 return TRUE; 3252 } 3253 } 3254 3255 // 3256 // Trim Language from the right to the next '-' character 3257 // 3258 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--); 3259 } 3260 3261 // 3262 // No matches were found 3263 // 3264 return FALSE; 3265 } 3266 3267 3268 CHAR8 * 3269 CVfrStringDB::GetVarStoreNameFormStringId ( 3270 IN EFI_STRING_ID StringId 3271 ) 3272 { 3273 FILE *pInFile = NULL; 3274 UINT32 NameOffset; 3275 UINT32 Length; 3276 UINT8 *StringPtr; 3277 CHAR8 *StringName; 3278 CHAR16 *UnicodeString; 3279 CHAR8 *VarStoreName = NULL; 3280 CHAR8 *DestTmp; 3281 UINT8 *Current; 3282 EFI_STATUS Status; 3283 CHAR8 LineBuf[EFI_IFR_MAX_LENGTH]; 3284 UINT8 BlockType; 3285 EFI_HII_STRING_PACKAGE_HDR *PkgHeader; 3286 3287 if (mStringFileName == '\0' ) { 3288 return NULL; 3289 } 3290 3291 if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) { 3292 return NULL; 3293 } 3294 3295 // 3296 // Get file length. 3297 // 3298 fseek (pInFile, 0, SEEK_END); 3299 Length = ftell (pInFile); 3300 fseek (pInFile, 0, SEEK_SET); 3301 3302 // 3303 // Get file data. 3304 // 3305 StringPtr = new UINT8[Length]; 3306 if (StringPtr == NULL) { 3307 fclose (pInFile); 3308 return NULL; 3309 } 3310 fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile); 3311 fclose (pInFile); 3312 3313 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr; 3314 // 3315 // Check the String package. 3316 // 3317 if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) { 3318 delete StringPtr; 3319 return NULL; 3320 } 3321 3322 // 3323 // Search the language, get best language base on RFC 4647 matching algorithm. 3324 // 3325 Current = StringPtr; 3326 while (!GetBestLanguage ("en", PkgHeader->Language)) { 3327 Current += PkgHeader->Header.Length; 3328 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current; 3329 // 3330 // If can't find string package base on language, just return the first string package. 3331 // 3332 if (Current - StringPtr >= Length) { 3333 Current = StringPtr; 3334 PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr; 3335 break; 3336 } 3337 } 3338 3339 Current += PkgHeader->HdrSize; 3340 // 3341 // Find the string block according the stringId. 3342 // 3343 Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType); 3344 if (Status != EFI_SUCCESS) { 3345 delete StringPtr; 3346 return NULL; 3347 } 3348 3349 // 3350 // Get varstore name according the string type. 3351 // 3352 switch (BlockType) { 3353 case EFI_HII_SIBT_STRING_SCSU: 3354 case EFI_HII_SIBT_STRING_SCSU_FONT: 3355 case EFI_HII_SIBT_STRINGS_SCSU: 3356 case EFI_HII_SIBT_STRINGS_SCSU_FONT: 3357 StringName = (CHAR8*)(Current + NameOffset); 3358 VarStoreName = new CHAR8[strlen(StringName) + 1]; 3359 strcpy (VarStoreName, StringName); 3360 break; 3361 case EFI_HII_SIBT_STRING_UCS2: 3362 case EFI_HII_SIBT_STRING_UCS2_FONT: 3363 case EFI_HII_SIBT_STRINGS_UCS2: 3364 case EFI_HII_SIBT_STRINGS_UCS2_FONT: 3365 UnicodeString = (CHAR16*)(Current + NameOffset); 3366 Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ; 3367 DestTmp = new CHAR8[Length / 2 + 1]; 3368 VarStoreName = DestTmp; 3369 while (*UnicodeString != '\0') { 3370 *(DestTmp++) = (CHAR8) *(UnicodeString++); 3371 } 3372 *DestTmp = '\0'; 3373 break; 3374 default: 3375 break; 3376 } 3377 3378 delete StringPtr; 3379 3380 return VarStoreName; 3381 } 3382 3383 EFI_STATUS 3384 CVfrStringDB::FindStringBlock ( 3385 IN UINT8 *StringData, 3386 IN EFI_STRING_ID StringId, 3387 OUT UINT32 *StringTextOffset, 3388 OUT UINT8 *BlockType 3389 ) 3390 { 3391 UINT8 *BlockHdr; 3392 EFI_STRING_ID CurrentStringId; 3393 UINT32 BlockSize; 3394 UINT32 Index; 3395 UINT8 *StringTextPtr; 3396 UINT32 Offset; 3397 UINT16 StringCount; 3398 UINT16 SkipCount; 3399 UINT8 Length8; 3400 EFI_HII_SIBT_EXT2_BLOCK Ext2; 3401 UINT32 Length32; 3402 UINT32 StringSize; 3403 3404 CurrentStringId = 1; 3405 3406 // 3407 // Parse the string blocks to get the string text and font. 3408 // 3409 BlockHdr = StringData; 3410 BlockSize = 0; 3411 Offset = 0; 3412 while (*BlockHdr != EFI_HII_SIBT_END) { 3413 switch (*BlockHdr) { 3414 case EFI_HII_SIBT_STRING_SCSU: 3415 Offset = sizeof (EFI_HII_STRING_BLOCK); 3416 StringTextPtr = BlockHdr + Offset; 3417 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1; 3418 CurrentStringId++; 3419 break; 3420 3421 case EFI_HII_SIBT_STRING_SCSU_FONT: 3422 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8); 3423 StringTextPtr = BlockHdr + Offset; 3424 BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1; 3425 CurrentStringId++; 3426 break; 3427 3428 case EFI_HII_SIBT_STRINGS_SCSU: 3429 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3430 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8); 3431 BlockSize += StringTextPtr - BlockHdr; 3432 3433 for (Index = 0; Index < StringCount; Index++) { 3434 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1; 3435 if (CurrentStringId == StringId) { 3436 *BlockType = *BlockHdr; 3437 *StringTextOffset = StringTextPtr - StringData; 3438 return EFI_SUCCESS; 3439 } 3440 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1; 3441 CurrentStringId++; 3442 } 3443 break; 3444 3445 case EFI_HII_SIBT_STRINGS_SCSU_FONT: 3446 memcpy ( 3447 &StringCount, 3448 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3449 sizeof (UINT16) 3450 ); 3451 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8); 3452 BlockSize += StringTextPtr - BlockHdr; 3453 3454 for (Index = 0; Index < StringCount; Index++) { 3455 BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1; 3456 if (CurrentStringId == StringId) { 3457 *BlockType = *BlockHdr; 3458 *StringTextOffset = StringTextPtr - StringData; 3459 return EFI_SUCCESS; 3460 } 3461 StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1; 3462 CurrentStringId++; 3463 } 3464 break; 3465 3466 case EFI_HII_SIBT_STRING_UCS2: 3467 Offset = sizeof (EFI_HII_STRING_BLOCK); 3468 StringTextPtr = BlockHdr + Offset; 3469 // 3470 // Use StringSize to store the size of the specified string, including the NULL 3471 // terminator. 3472 // 3473 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3474 BlockSize += Offset + StringSize; 3475 CurrentStringId++; 3476 break; 3477 3478 case EFI_HII_SIBT_STRING_UCS2_FONT: 3479 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16); 3480 StringTextPtr = BlockHdr + Offset; 3481 // 3482 // Use StrSize to store the size of the specified string, including the NULL 3483 // terminator. 3484 // 3485 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3486 BlockSize += Offset + StringSize; 3487 CurrentStringId++; 3488 break; 3489 3490 case EFI_HII_SIBT_STRINGS_UCS2: 3491 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16); 3492 StringTextPtr = BlockHdr + Offset; 3493 BlockSize += Offset; 3494 memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3495 for (Index = 0; Index < StringCount; Index++) { 3496 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3497 BlockSize += StringSize; 3498 if (CurrentStringId == StringId) { 3499 *BlockType = *BlockHdr; 3500 *StringTextOffset = StringTextPtr - StringData; 3501 return EFI_SUCCESS; 3502 } 3503 StringTextPtr = StringTextPtr + StringSize; 3504 CurrentStringId++; 3505 } 3506 break; 3507 3508 case EFI_HII_SIBT_STRINGS_UCS2_FONT: 3509 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16); 3510 StringTextPtr = BlockHdr + Offset; 3511 BlockSize += Offset; 3512 memcpy ( 3513 &StringCount, 3514 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3515 sizeof (UINT16) 3516 ); 3517 for (Index = 0; Index < StringCount; Index++) { 3518 StringSize = GetUnicodeStringTextSize (StringTextPtr); 3519 BlockSize += StringSize; 3520 if (CurrentStringId == StringId) { 3521 *BlockType = *BlockHdr; 3522 *StringTextOffset = StringTextPtr - StringData; 3523 return EFI_SUCCESS; 3524 } 3525 StringTextPtr = StringTextPtr + StringSize; 3526 CurrentStringId++; 3527 } 3528 break; 3529 3530 case EFI_HII_SIBT_DUPLICATE: 3531 if (CurrentStringId == StringId) { 3532 // 3533 // Incoming StringId is an id of a duplicate string block. 3534 // Update the StringId to be the previous string block. 3535 // Go back to the header of string block to search. 3536 // 3537 memcpy ( 3538 &StringId, 3539 BlockHdr + sizeof (EFI_HII_STRING_BLOCK), 3540 sizeof (EFI_STRING_ID) 3541 ); 3542 CurrentStringId = 1; 3543 BlockSize = 0; 3544 } else { 3545 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK); 3546 CurrentStringId++; 3547 } 3548 break; 3549 3550 case EFI_HII_SIBT_SKIP1: 3551 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK))); 3552 CurrentStringId = (UINT16) (CurrentStringId + SkipCount); 3553 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK); 3554 break; 3555 3556 case EFI_HII_SIBT_SKIP2: 3557 memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16)); 3558 CurrentStringId = (UINT16) (CurrentStringId + SkipCount); 3559 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); 3560 break; 3561 3562 case EFI_HII_SIBT_EXT1: 3563 memcpy ( 3564 &Length8, 3565 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3566 sizeof (UINT8) 3567 ); 3568 BlockSize += Length8; 3569 break; 3570 3571 case EFI_HII_SIBT_EXT2: 3572 memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK)); 3573 BlockSize += Ext2.Length; 3574 break; 3575 3576 case EFI_HII_SIBT_EXT4: 3577 memcpy ( 3578 &Length32, 3579 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8), 3580 sizeof (UINT32) 3581 ); 3582 3583 BlockSize += Length32; 3584 break; 3585 3586 default: 3587 break; 3588 } 3589 3590 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) { 3591 *StringTextOffset = BlockHdr - StringData + Offset; 3592 *BlockType = *BlockHdr; 3593 3594 if (StringId == CurrentStringId - 1) { 3595 // 3596 // if only one skip item, return EFI_NOT_FOUND. 3597 // 3598 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) { 3599 return EFI_NOT_FOUND; 3600 } else { 3601 return EFI_SUCCESS; 3602 } 3603 } 3604 3605 if (StringId < CurrentStringId - 1) { 3606 return EFI_NOT_FOUND; 3607 } 3608 } 3609 BlockHdr = StringData + BlockSize; 3610 } 3611 3612 return EFI_NOT_FOUND; 3613 } 3614 3615 UINT32 3616 CVfrStringDB::GetUnicodeStringTextSize ( 3617 IN UINT8 *StringSrc 3618 ) 3619 { 3620 UINT32 StringSize; 3621 CHAR16 *StringPtr; 3622 3623 StringSize = sizeof (CHAR16); 3624 StringPtr = (UINT16*)StringSrc; 3625 while (*StringPtr++ != L'\0') { 3626 StringSize += sizeof (CHAR16); 3627 } 3628 3629 return StringSize; 3630 } 3631 3632 BOOLEAN VfrCompatibleMode = FALSE; 3633 3634 CVfrVarDataTypeDB gCVfrVarDataTypeDB; 3635 3636 3637