Changeset 90114 in vbox
- Timestamp:
- Jul 9, 2021 11:12:53 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/formats/efi-varstore.h
r90061 r90114 115 115 116 116 /** Value in EFI_AUTH_VAR_HEADER::u16StartId for a valid variable header. */ 117 #define EFI_AUTH_VAR_HEADER_START 0x55aa117 #define EFI_AUTH_VAR_HEADER_START 0x55aa 118 118 /** @name Possible variable states. 119 119 * @{ */ 120 120 /** Variable is in the process of being deleted. */ 121 #define EFI_AUTH_VAR_HEADER_STATE_IN_DELETED_TRANSITION 0xfe121 #define EFI_AUTH_VAR_HEADER_STATE_IN_DELETED_TRANSITION 0xfe 122 122 /** Variable was deleted. */ 123 #define EFI_AUTH_VAR_HEADER_STATE_DELETED 0xfd123 #define EFI_AUTH_VAR_HEADER_STATE_DELETED 0xfd 124 124 /** Variable has only a valid header right now. */ 125 #define EFI_AUTH_VAR_HEADER_STATE_HDR_VALID_ONLY 0x7f125 #define EFI_AUTH_VAR_HEADER_STATE_HDR_VALID_ONLY 0x7f 126 126 /** Variable header, name and data are all valid. */ 127 #define EFI_AUTH_VAR_HEADER_STATE_ADDED 0x3f127 #define EFI_AUTH_VAR_HEADER_STATE_ADDED 0x3f 128 128 /** @} */ 129 129 130 130 131 /** @name Possible variable attributes. 132 * @{ */ 133 /** The variable is stored in non volatile memory. */ 134 #define EFI_VAR_HEADER_ATTR_NON_VOLATILE RT_BIT_32(0) 135 /** The variable is accessible by the EFI bootservice stage. */ 136 #define EFI_VAR_HEADER_ATTR_BOOTSERVICE_ACCESS RT_BIT_32(1) 137 /** The variable is accessible during runtime. */ 138 #define EFI_VAR_HEADER_ATTR_RUNTIME_ACCESS RT_BIT_32(2) 139 /** The variable contains an hardware error record. */ 140 #define EFI_VAR_HEADER_ATTR_HW_ERROR_RECORD RT_BIT_32(3) 141 /** The variable can be modified only by an authenticated source. */ 142 #define EFI_AUTH_VAR_HEADER_ATTR_AUTH_WRITE_ACCESS RT_BIT_32(4) 143 /** The variable was written with a time based authentication. */ 144 #define EFI_AUTH_VAR_HEADER_ATTR_TIME_BASED_AUTH_WRITE_ACCESS RT_BIT_32(5) 145 /** The variable can be appended. */ 146 #define EFI_AUTH_VAR_HEADER_ATTR_APPEND_WRITE RT_BIT_32(6) 147 /** @} */ 148 131 149 #endif /* !IPRT_INCLUDED_formats_efi_varstore_h */ 132 150 -
trunk/src/VBox/Runtime/common/efi/efitime.cpp
r90065 r90114 54 54 RTTIME Time; RT_ZERO(Time); 55 55 56 Time.i32Year = pEfiTime->u16Year + 1900;56 Time.i32Year = pEfiTime->u16Year; 57 57 Time.u8Month = pEfiTime->u8Month; 58 58 Time.u8MonthDay = pEfiTime->u8Day; … … 90 90 91 91 RT_ZERO(*pEfiTime); 92 pEfiTime->u16Year = Time.i32Year < 190092 pEfiTime->u16Year = Time.i32Year < 0 93 93 ? 0 94 : Time.i32Year - 1900;94 : (uint16_t)Time.i32Year; 95 95 pEfiTime->u8Month = Time.u8Month; 96 96 pEfiTime->u8Day = Time.u8MonthDay; -
trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp
r90068 r90114 66 66 /** Pointer to the owning variable store. */ 67 67 PRTEFIVARSTORE pVarStore; 68 /** Offset of the variable header located in the backing image . */68 /** Offset of the variable header located in the backing image - 0 if not written yet. */ 69 69 uint64_t offVarHdr; 70 /** Offset of the variable data located in the backing image . */70 /** Offset of the variable data located in the backing image - 0 if not written yet. */ 71 71 uint64_t offVarData; 72 /** The validated variable header. */ 73 EFI_AUTH_VAR_HEADER VarHdr; 72 /** Monotonic counter value. */ 73 uint64_t cMonotonic; 74 /** Size of the variable data in bytes. */ 75 uint32_t cbData; 76 /** Index of the assoicated public key. */ 77 uint32_t idPubKey; 78 /** Attributes for the variable. */ 79 uint32_t fAttr; 74 80 /** Name of the variable. */ 75 81 char *pszName; 76 /** The time creation/update time. */ 82 /** The raw EFI timestamp as read from the header. */ 83 EFI_TIME EfiTimestamp; 84 /** The creation/update time. */ 77 85 RTTIMESPEC Time; 78 86 /** The vendor UUID of the variable. */ … … 88 96 typedef struct RTEFIGUID 89 97 { 90 /** The UUID r presentation of the GUID. */98 /** The UUID representation of the GUID. */ 91 99 RTUUID Uuid; 92 100 /** Pointer to the array of indices into RTEFIVARSTORE::paVars. */ … … 119 127 120 128 /** Size of the variable store (minus the header). */ 121 size_tcbVarStore;129 uint64_t cbVarStore; 122 130 /** Start offset into the backing image where the variable data starts. */ 123 131 uint64_t offStoreData; … … 155 163 /** 'by-name' directory. */ 156 164 RTEFIVARSTOREDIRTYPE_BY_NAME, 157 /** 'by- guid' directory. */165 /** 'by-uuid' directory. */ 158 166 RTEFIVARSTOREDIRTYPE_BY_GUID, 167 /** 'raw' directory. */ 168 RTEFIVARSTOREDIRTYPE_RAW, 159 169 /** Specific 'by-uuid/{...}' directory. */ 160 170 RTEFIVARSTOREDIRTYPE_GUID, 171 /** Specific 'raw/{...}' directory. */ 172 RTEFIVARSTOREDIRTYPE_RAW_ENTRY, 161 173 /** 32bit blowup hack. */ 162 174 RTEFIVARSTOREDIRTYPE_32BIT_HACK = 0x7fffffff … … 177 189 /** The variable store associated with this directory. */ 178 190 PRTEFIVARSTORE pVarStore; 191 /** Time when the directory was created. */ 192 RTTIMESPEC Time; 179 193 /** Pointer to the GUID entry, only valid for RTEFIVARSTOREDIRTYPE_GUID. */ 180 194 PRTEFIGUID pGuid; 181 /** T ime when the directory was created. */182 RTTIMESPEC Time;195 /** The variable ID, only valid for RTEFIVARSTOREDIRTYPE_RAW_ENTRY. */ 196 uint32_t idVar; 183 197 } RTEFIVARSTOREDIR; 184 198 /** Pointer to an Variable store directory. */ … … 187 201 188 202 /** 203 * File type. 204 */ 205 typedef enum RTEFIVARSTOREFILETYPE 206 { 207 /** Invalid type, do not use. */ 208 RTEFIVARSTOREFILETYPE_INVALID = 0, 209 /** File accesses the data portion of the variable. */ 210 RTEFIVARSTOREFILETYPE_DATA, 211 /** File accesses the attributes of the variable. */ 212 RTEFIVARSTOREFILETYPE_ATTR, 213 /** File accesses the UUID of the variable. */ 214 RTEFIVARSTOREFILETYPE_UUID, 215 /** File accesses the public key index of the variable. */ 216 RTEFIVARSTOREFILETYPE_PUBKEY, 217 /** File accesses the raw EFI Time of the variable. */ 218 RTEFIVARSTOREFILETYPE_TIME, 219 /** The monotonic counter (deprecated). */ 220 RTEFIVARSTOREFILETYPE_MONOTONIC, 221 /** 32bit hack. */ 222 RTEFIVARSTOREFILETYPE_32BIT_HACK = 0x7fffffff, 223 } RTEFIVARSTOREFILETYPE; 224 225 226 /** 227 * Raw file type entry. 228 */ 229 typedef struct RTEFIVARSTOREFILERAWENTRY 230 { 231 /** Name of the entry. */ 232 const char *pszName; 233 /** The associated file type. */ 234 RTEFIVARSTOREFILETYPE enmType; 235 /** File size of the object, 0 if dynamic. */ 236 size_t cbObject; 237 /** Offset of the item in the variable header. */ 238 uint32_t offObject; 239 } RTEFIVARSTOREFILERAWENTRY; 240 /** Pointer to a raw file type entry. */ 241 typedef RTEFIVARSTOREFILERAWENTRY *PRTEFIVARSTOREFILERAWENTRY; 242 /** Pointer to a const file type entry. */ 243 typedef const RTEFIVARSTOREFILERAWENTRY *PCRTEFIVARSTOREFILERAWENTRY; 244 245 246 /** 189 247 * Open file instance. 190 248 */ 191 249 typedef struct RTEFIVARFILE 192 250 { 251 /** The file type. */ 252 PCRTEFIVARSTOREFILERAWENTRY pEntry; 193 253 /** Variable store this file belongs to. */ 194 PRTEFIVARSTORE pVarStore;254 PRTEFIVARSTORE pVarStore; 195 255 /** The underlying variable structure. */ 196 PRTEFIVAR pVar;256 PRTEFIVAR pVar; 197 257 /** Current offset into the file for I/O. */ 198 RTFOFF offFile;258 RTFOFF offFile; 199 259 } RTEFIVARFILE; 200 260 /** Pointer to an open file instance. */ … … 202 262 203 263 264 /** 265 * Raw files for accessing specific items in the variable header. 266 */ 267 static const RTEFIVARSTOREFILERAWENTRY g_aRawFiles[] = 268 { 269 { "attr", RTEFIVARSTOREFILETYPE_ATTR, sizeof(uint32_t), RT_UOFFSETOF(RTEFIVAR, fAttr) }, 270 { "data", RTEFIVARSTOREFILETYPE_DATA, 0, 0 }, 271 { "uuid", RTEFIVARSTOREFILETYPE_UUID, sizeof(RTUUID), RT_UOFFSETOF(RTEFIVAR, Uuid) }, 272 { "pubkey", RTEFIVARSTOREFILETYPE_PUBKEY, sizeof(uint32_t), RT_UOFFSETOF(RTEFIVAR, idPubKey) }, 273 { "time", RTEFIVARSTOREFILETYPE_TIME, sizeof(EFI_TIME), RT_UOFFSETOF(RTEFIVAR, EfiTimestamp) }, 274 { "monotonic", RTEFIVARSTOREFILETYPE_MONOTONIC, sizeof(uint64_t), RT_UOFFSETOF(RTEFIVAR, cMonotonic) } 275 }; 276 277 #define RTEFIVARSTORE_FILE_ENTRY_DATA 1 278 279 204 280 /********************************************************************************************************************************* 205 281 * Internal Functions * 206 282 *********************************************************************************************************************************/ 207 static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, PRTEFIGUID pGuid, PRTVFSOBJ phVfsObj); 283 static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, 284 PRTEFIGUID pGuid, uint32_t idVar, PRTVFSOBJ phVfsObj); 208 285 209 286 … … 428 505 429 506 430 /* 431 * 432 * File operations. 433 * File operations. 434 * File operations. 435 * 436 */ 437 438 /** 439 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 440 */ 441 static DECLCALLBACK(int) rtEfiVarStoreFile_Close(void *pvThis) 442 { 443 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 444 LogFlow(("rtEfiVarStoreFile_Close(%p/%p)\n", pThis, pThis->pVar)); 445 RT_NOREF(pThis); 446 return VINF_SUCCESS; 447 } 448 449 450 /** 451 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 452 */ 453 static DECLCALLBACK(int) rtEfiVarStoreFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 454 { 455 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 456 return rtEfiVarStore_QueryInfo(RT_LE2H_U32(pThis->pVar->VarHdr.cbData), false /*fIsDir*/, 457 &pThis->pVar->Time, pObjInfo, enmAddAttr); 458 } 459 460 461 /** 462 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 463 */ 464 static DECLCALLBACK(int) rtEfiVarStoreFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 465 { 466 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 507 /** 508 * Reads variable data from the given memory area. 509 * 510 * @returns IPRT status code. 511 * @param pThis The EFI variable file instance. 512 * @param pvData Pointer to the start of the data. 513 * @param cbData Size of the variable data in bytes. 514 * @param off Where to start reading relative from the data start offset. 515 * @param pSgBuf Where to store the read data. 516 * @param pcbRead Where to return the number of bytes read, optional. 517 */ 518 static int rtEfiVarStoreFile_ReadMem(PRTEFIVARFILE pThis, const void *pvData, size_t cbData, 519 RTFOFF off, PCRTSGBUF pSgBuf, size_t *pcbRead) 520 { 521 int rc = VINF_SUCCESS; 522 size_t cbRead = pSgBuf->paSegs[0].cbSeg; 523 size_t cbThisRead = RT_MIN(cbData - off, cbRead); 524 const uint8_t *pbData = (const uint8_t *)pvData; 525 if (!pcbRead) 526 { 527 if (cbThisRead == cbRead) 528 memcpy(pSgBuf->paSegs[0].pvSeg, &pbData[off], cbThisRead); 529 else 530 rc = VERR_EOF; 531 532 if (RT_SUCCESS(rc)) 533 pThis->offFile = off + cbThisRead; 534 Log6(("rtFsEfiVarStore_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc)); 535 } 536 else 537 { 538 if ((uint64_t)off >= cbData) 539 { 540 *pcbRead = 0; 541 rc = VINF_EOF; 542 } 543 else 544 { 545 memcpy(pSgBuf->paSegs[0].pvSeg, &pbData[off], cbThisRead); 546 /* Return VINF_EOF if beyond end-of-file. */ 547 if (cbThisRead < cbRead) 548 rc = VINF_EOF; 549 pThis->offFile = off + cbThisRead; 550 *pcbRead = cbThisRead; 551 } 552 Log6(("rtEfiVarStoreFile_ReadMem: off=%#RX64 cbSeg=%#x -> %Rrc *pcbRead=%#x\n", off, pSgBuf->paSegs[0].cbSeg, rc, *pcbRead)); 553 } 554 555 return rc; 556 } 557 558 559 /** 560 * Reads variable data from the given range. 561 * 562 * @returns IPRT status code. 563 * @param pThis The EFI variable file instance. 564 * @param offData Where the data starts in the backing storage. 565 * @param cbData Size of the variable data in bytes. 566 * @param off Where to start reading relative from the data start offset. 567 * @param pSgBuf Where to store the read data. 568 * @param pcbRead Where to return the number of bytes read, optional. 569 */ 570 static int rtEfiVarStoreFile_ReadFile(PRTEFIVARFILE pThis, uint64_t offData, size_t cbData, 571 RTFOFF off, PCRTSGBUF pSgBuf, size_t *pcbRead) 572 { 573 int rc; 467 574 PRTEFIVARSTORE pVarStore = pThis->pVarStore; 468 AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3);469 RT_NOREF(fBlocking);470 471 if (off == -1)472 off = pThis->offFile;473 else474 AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3);475 476 int rc;477 575 size_t cbRead = pSgBuf->paSegs[0].cbSeg; 478 size_t cbData = RT_LE2H_U32(pThis->pVar->VarHdr.cbData);479 576 size_t cbThisRead = RT_MIN(cbData - off, cbRead); 480 uint64_t offStart = pThis->pVar->offVarData + off;577 uint64_t offStart = offData + off; 481 578 if (!pcbRead) 482 579 { … … 519 616 520 617 /** 618 * Flush the variable store to the backing storage. This will remove any 619 * deleted variables in the backing storage. 620 * 621 * @returns IPRT status code. 622 * @param pThis The EFI variable store instance. 623 */ 624 static int rtEfiVarStore_Flush(PRTEFIVARSTORE pThis) 625 { 626 int rc = VINF_SUCCESS; 627 uint64_t offCur = pThis->offStoreData; 628 void *pvData = NULL; 629 size_t cbData = 0; 630 size_t cbDataMax = 0; 631 632 for (uint32_t i = 0; i < pThis->cVars && RT_SUCCESS(rc); i++) 633 { 634 PRTUTF16 pwszName = NULL; 635 size_t cwcLen = 0; 636 PRTEFIVAR pVar = &pThis->paVars[i]; 637 638 rc = RTStrToUtf16Ex(pVar->pszName, RTSTR_MAX, &pwszName, 0, &cwcLen); 639 if (RT_SUCCESS(rc)) 640 { 641 cwcLen++; /* Include the terminator. */ 642 643 /* Read in the data of the variable if it exists. */ 644 if (pVar->offVarData) 645 { 646 if (cbDataMax < pVar->cbData) 647 { 648 size_t cbDataMaxNew = pVar->cbData; 649 void *pvDataNew = RTMemRealloc(pvData, cbDataMaxNew); 650 if (pvDataNew) 651 { 652 pvData = pvDataNew; 653 cbDataMax = cbDataMaxNew; 654 } 655 else 656 rc = VERR_NO_MEMORY; 657 } 658 659 cbData = pVar->cbData; 660 661 if (RT_SUCCESS(rc)) 662 rc = RTVfsFileReadAt(pThis->hVfsBacking, pVar->offVarData, pvData, cbData, NULL); 663 } 664 665 /* Write out the variable. */ 666 if (RT_SUCCESS(rc)) 667 { 668 EFI_AUTH_VAR_HEADER VarHdr; 669 size_t cbName = cwcLen * sizeof(RTUTF16); 670 671 VarHdr.u16StartId = RT_H2LE_U16(EFI_AUTH_VAR_HEADER_START); 672 VarHdr.bState = EFI_AUTH_VAR_HEADER_STATE_ADDED; 673 VarHdr.bRsvd = 0; 674 VarHdr.fAttr = RT_H2LE_U32(pVar->fAttr); 675 VarHdr.cMonotonic = RT_H2LE_U64(pVar->cMonotonic); 676 VarHdr.idPubKey = RT_H2LE_U32(pVar->idPubKey); 677 VarHdr.cbName = RT_H2LE_U32(cbName); 678 VarHdr.cbData = RT_H2LE_U32(pVar->cbData); 679 RTEfiGuidFromUuid(&VarHdr.GuidVendor, &pVar->Uuid); 680 memcpy(&VarHdr.Timestamp, &pVar->EfiTimestamp, sizeof(pVar->EfiTimestamp)); 681 682 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &VarHdr, sizeof(VarHdr), NULL); 683 if (RT_SUCCESS(rc)) 684 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr), pwszName, cbName, NULL); 685 if (RT_SUCCESS(rc)) 686 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, pvData, cbData, NULL); 687 if (RT_SUCCESS(rc)) 688 { 689 offCur += sizeof(VarHdr) + cbName + cbData; 690 uint64_t offCurAligned = RT_ALIGN_64(offCur, sizeof(uint16_t)); 691 if (offCurAligned > offCur) 692 { 693 /* Should be at most 1 byte to align the next variable to a 16bit boundary. */ 694 Assert(offCurAligned - offCur == 1); 695 uint8_t bFill = 0xff; 696 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &bFill, sizeof(bFill), NULL); 697 } 698 699 offCur = offCurAligned; 700 } 701 } 702 703 RTUtf16Free(pwszName); 704 } 705 } 706 707 if (RT_SUCCESS(rc)) 708 { 709 /* Fill the remainder with 0xff as it would be the case for a real NAND flash device. */ 710 uint8_t abFF[512]; 711 memset(&abFF[0], 0xff, sizeof(abFF)); 712 713 uint64_t offStart = offCur; 714 uint64_t offEnd = pThis->offStoreData + pThis->cbVarStore; 715 while ( offStart < offEnd 716 && RT_SUCCESS(rc)) 717 { 718 size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart); 719 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offStart, &abFF[0], cbThisWrite, NULL); 720 offStart += cbThisWrite; 721 } 722 } 723 724 if (pvData) 725 RTMemFree(pvData); 726 727 return rc; 728 } 729 730 731 /* 732 * 733 * File operations. 734 * File operations. 735 * File operations. 736 * 737 */ 738 739 /** 740 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 741 */ 742 static DECLCALLBACK(int) rtEfiVarStoreFile_Close(void *pvThis) 743 { 744 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 745 LogFlow(("rtEfiVarStoreFile_Close(%p/%p)\n", pThis, pThis->pVar)); 746 RT_NOREF(pThis); 747 return VINF_SUCCESS; 748 } 749 750 751 /** 752 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 753 */ 754 static DECLCALLBACK(int) rtEfiVarStoreFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 755 { 756 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 757 uint64_t cbObject = pThis->pEntry->cbObject > 0 758 ? pThis->pEntry->cbObject 759 : pThis->pVar->cbData; 760 return rtEfiVarStore_QueryInfo(cbObject, false /*fIsDir*/, &pThis->pVar->Time, pObjInfo, enmAddAttr); 761 } 762 763 764 /** 765 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 766 */ 767 static DECLCALLBACK(int) rtEfiVarStoreFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 768 { 769 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 770 PRTEFIVAR pVar = pThis->pVar; 771 AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3); 772 RT_NOREF(fBlocking); 773 774 if (off == -1) 775 off = pThis->offFile; 776 else 777 AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3); 778 779 int rc; 780 if (pThis->pEntry->cbObject) 781 rc = rtEfiVarStoreFile_ReadMem(pThis, (const uint8_t *)pVar + pThis->pEntry->offObject, pThis->pEntry->cbObject, off, pSgBuf, pcbRead); 782 else 783 rc = rtEfiVarStoreFile_ReadFile(pThis, pVar->offVarData, pVar->cbData, off, pSgBuf, pcbRead); 784 785 return rc; 786 } 787 788 789 /** 521 790 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite} 522 791 */ … … 593 862 break; 594 863 case RTFILE_SEEK_END: 595 offNew = RT_LE2H_U32(pThis->pVar->VarHdr.cbData)+ offSeek;864 offNew = pThis->pVar->cbData + offSeek; 596 865 break; 597 866 case RTFILE_SEEK_CURRENT: … … 617 886 { 618 887 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 619 *pcbFile = (uint64_t)RT_LE2H_U32(pThis->pVar->VarHdr.cbData); 888 if (pThis->pEntry->cbObject) 889 *pcbFile = pThis->pEntry->cbObject; 890 else 891 *pcbFile = (uint64_t)pThis->pVar->cbData; 620 892 return VINF_SUCCESS; 621 893 } … … 692 964 * @param pThis The ext volume instance. 693 965 * @param fOpen Open flags passed. 694 * @param iInode The inode for the file. 966 * @param pVar The variable this file accesses. 967 * @param pEntry File type entry. 695 968 * @param phVfsFile Where to store the VFS file handle on success. 696 969 * @param pErrInfo Where to record additional error information on error, optional. 697 970 */ 698 971 static int rtEfiVarStore_NewFile(PRTEFIVARSTORE pThis, uint64_t fOpen, PRTEFIVAR pVar, 699 P RTVFSOBJ phVfsObj)972 PCRTEFIVARSTOREFILERAWENTRY pEntry, PRTVFSOBJ phVfsObj) 700 973 { 701 974 RTVFSFILE hVfsFile; … … 705 978 if (RT_SUCCESS(rc)) 706 979 { 980 pNewFile->pEntry = pEntry; 707 981 pNewFile->pVarStore = pThis; 708 982 pNewFile->pVar = pVar; … … 807 1081 if ( pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_NAME 808 1082 || pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_GUID 1083 || pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW 809 1084 || pThis->enmType == RTEFIVARSTOREDIRTYPE_ROOT) 810 1085 enmDirTypeNew = RTEFIVARSTOREDIRTYPE_ROOT; 811 1086 else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_GUID) 812 1087 enmDirTypeNew = RTEFIVARSTOREDIRTYPE_BY_GUID; 1088 else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW_ENTRY) 1089 enmDirTypeNew = RTEFIVARSTOREDIRTYPE_RAW; 813 1090 else 814 1091 AssertMsgFailedReturn(("Invalid directory type %d\n", pThis->enmType), VERR_ACCESS_DENIED); … … 821 1098 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 822 1099 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE) 823 rc = rtEfiVarStore_NewDirByType(pVarStore, enmDirTypeNew, NULL /*pGuid*/, phVfsObj);1100 rc = rtEfiVarStore_NewDirByType(pVarStore, enmDirTypeNew, NULL /*pGuid*/, 0 /*idVar*/, phVfsObj); 824 1101 else 825 1102 rc = VERR_ACCESS_DENIED; … … 845 1122 { 846 1123 if (!strcmp(pszEntry, "by-name")) 847 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_NAME, NULL /*pGuid*/, phVfsObj); 1124 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_NAME, 1125 NULL /*pGuid*/, 0 /*idVar*/, phVfsObj); 848 1126 else if (!strcmp(pszEntry, "by-uuid")) 849 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_GUID, NULL /*pGuid*/, phVfsObj); 1127 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_GUID, 1128 NULL /*pGuid*/, 0 /*idVar*/, phVfsObj); 1129 else if (!strcmp(pszEntry, "raw")) 1130 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW, 1131 NULL /*pGuid*/, 0 /*idVar*/, phVfsObj); 850 1132 else 851 1133 rc = VERR_FILE_NOT_FOUND; … … 854 1136 case RTEFIVARSTOREDIRTYPE_GUID: /** @todo This looks through all variables, not only the ones with the GUID. */ 855 1137 case RTEFIVARSTOREDIRTYPE_BY_NAME: 1138 case RTEFIVARSTOREDIRTYPE_RAW: 856 1139 { 857 1140 /* Look for the name. */ 858 1141 for (uint32_t i = 0; i < pVarStore->cVars; i++) 859 1142 if (!strcmp(pszEntry, pVarStore->paVars[i].pszName)) 860 return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[i], phVfsObj); 1143 { 1144 if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW) 1145 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW_ENTRY, 1146 NULL /*pGuid*/, i /*idVar*/, phVfsObj); 1147 else 1148 return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[i], 1149 &g_aRawFiles[RTEFIVARSTORE_FILE_ENTRY_DATA], phVfsObj); 1150 } 861 1151 862 1152 rc = VERR_FILE_NOT_FOUND; … … 874 1164 875 1165 if (!strcmp(pszEntry, szUuid)) 876 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_GUID, pGuid, phVfsObj); 1166 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_GUID, 1167 pGuid, 0 /*idVar*/, phVfsObj); 877 1168 } 1169 1170 rc = VERR_FILE_NOT_FOUND; 1171 break; 1172 } 1173 case RTEFIVARSTOREDIRTYPE_RAW_ENTRY: 1174 { 1175 /* Look for the name. */ 1176 for (uint32_t i = 0; i < RT_ELEMENTS(g_aRawFiles); i++) 1177 if (!strcmp(pszEntry, g_aRawFiles[i].pszName)) 1178 return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[pThis->idVar], 1179 &g_aRawFiles[i], phVfsObj); 878 1180 879 1181 rc = VERR_FILE_NOT_FOUND; … … 895 1197 static DECLCALLBACK(int) rtEfiVarStoreDir_CreateDir(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir) 896 1198 { 897 RT_NOREF(pvThis, pszSubDir, fMode, phVfsDir); 1199 PRTEFIVARSTOREDIR pThis = (PRTEFIVARSTOREDIR)pvThis; 1200 PRTEFIVARSTORE pVarStore = pThis->pVarStore; 898 1201 LogFlowFunc(("\n")); 899 return VERR_WRITE_PROTECT; 1202 1203 RT_NOREF(pszSubDir, fMode, phVfsDir); 1204 1205 if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY) 1206 return VERR_WRITE_PROTECT; 1207 1208 /* We support creating directories only for GUIDs. */ 1209 if (pThis->enmType != RTEFIVARSTOREDIRTYPE_BY_GUID) 1210 return VERR_NOT_SUPPORTED; 1211 1212 RTUUID Uuid; 1213 int rc = RTUuidFromStr(&Uuid, pszSubDir); 1214 if (RT_FAILURE(rc)) 1215 return VERR_NOT_SUPPORTED; 1216 1217 PRTEFIGUID pGuid = rtEfiVarStore_GetGuid(pVarStore, &Uuid); 1218 if (pGuid) 1219 return VERR_ALREADY_EXISTS; 1220 1221 pGuid = rtEfiVarStore_AddGuid(pVarStore, &Uuid); 1222 if (!pGuid) 1223 return VERR_NO_MEMORY; 1224 1225 return VINF_SUCCESS; 900 1226 } 901 1227 … … 1000 1326 cbObject = 1; 1001 1327 fIsDir = true; 1328 } 1329 else if (pThis->idxNext == 2) 1330 { 1331 pszName = "raw"; 1332 cbName = sizeof("raw"); 1333 cbObject = 1; 1334 fIsDir = true; 1002 1335 fNoMoreFiles = true; 1003 1336 } … … 1005 1338 } 1006 1339 case RTEFIVARSTOREDIRTYPE_BY_NAME: 1340 case RTEFIVARSTOREDIRTYPE_RAW: 1007 1341 { 1008 1342 PRTEFIVAR pVar = &pVarStore->paVars[pThis->idxNext]; … … 1011 1345 pszName = pVar->pszName; 1012 1346 cbName = strlen(pszName) + 1; 1013 cbObject = RT_LE2H_U32(pVar->VarHdr.cbData);1347 cbObject = pVar->cbData; 1014 1348 pTimeSpec = &pVar->Time; 1349 if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW) 1350 fIsDir = true; 1015 1351 break; 1016 1352 } … … 1036 1372 pszName = pVar->pszName; 1037 1373 cbName = strlen(pszName) + 1; 1038 cbObject = RT_LE2H_U32(pVar->VarHdr.cbData); 1374 cbObject = pVar->cbData; 1375 pTimeSpec = &pVar->Time; 1376 break; 1377 } 1378 case RTEFIVARSTOREDIRTYPE_RAW_ENTRY: 1379 { 1380 PCRTEFIVARSTOREFILERAWENTRY pEntry = &g_aRawFiles[pThis->idxNext]; 1381 PRTEFIVAR pVar = &pVarStore->paVars[pThis->idVar]; 1382 1383 if (pThis->idxNext + 1 == RT_ELEMENTS(g_aRawFiles)) 1384 fNoMoreFiles = true; 1385 pszName = pEntry->pszName; 1386 cbName = strlen(pszName) + 1; 1387 cbObject = pEntry->cbObject; 1388 if (!cbObject) 1389 cbObject = pVar->cbData; 1039 1390 pTimeSpec = &pVar->Time; 1040 1391 break; … … 1111 1462 1112 1463 1113 static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, PRTEFIGUID pGuid, PRTVFSOBJ phVfsObj) 1464 static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, 1465 PRTEFIGUID pGuid, uint32_t idVar, PRTVFSOBJ phVfsObj) 1114 1466 { 1115 1467 RTVFSDIR hVfsDir; … … 1123 1475 pDir->pVarStore = pThis; 1124 1476 pDir->pGuid = pGuid; 1477 pDir->idVar = idVar; 1125 1478 RTTimeNow(&pDir->Time); 1126 1479 … … 1148 1501 { 1149 1502 PRTEFIVARSTORE pThis = (PRTEFIVARSTORE)pvThis; 1503 1504 /* Write the variable store if in read/write mode. */ 1505 if (!(pThis->fMntFlags & RTVFSMNT_F_READ_ONLY)) 1506 { 1507 int rc = rtEfiVarStore_Flush(pThis); 1508 if (RT_FAILURE(rc)) 1509 return rc; 1510 } 1150 1511 1151 1512 /* … … 1429 1790 pVar->offVarHdr = offVar; 1430 1791 pVar->offVarData = offVar + sizeof(VarHdr) + RT_LE2H_U32(VarHdr.cbName); 1431 memcpy(&pVar->VarHdr, &VarHdr, sizeof(VarHdr)); 1792 pVar->fAttr = RT_LE2H_U32(VarHdr.fAttr); 1793 pVar->cMonotonic = RT_LE2H_U64(VarHdr.cMonotonic); 1794 pVar->idPubKey = RT_LE2H_U32(VarHdr.idPubKey); 1795 pVar->cbData = RT_LE2H_U32(VarHdr.cbData); 1796 memcpy(&pVar->EfiTimestamp, &VarHdr.Timestamp, sizeof(VarHdr.Timestamp)); 1797 1432 1798 if (VarHdr.Timestamp.u8Month) 1433 1799 RTEfiTimeToTimeSpec(&pVar->Time, &VarHdr.Timestamp); … … 1666 2032 size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart); 1667 2033 rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL); 2034 offStart += cbThisWrite; 1668 2035 } 1669 2036 }
Note:
See TracChangeset
for help on using the changeset viewer.