Changeset 90125 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jul 9, 2021 2:05:45 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp
r90116 r90125 66 66 /** Pointer to the owning variable store. */ 67 67 PRTEFIVARSTORE pVarStore; 68 /** Offset of the variable header located in the backing image - 0 if not written yet. */69 uint64_t offVarHdr;70 68 /** Offset of the variable data located in the backing image - 0 if not written yet. */ 71 69 uint64_t offVarData; 70 /** Pointer to the in memory data, NULL if not yet read. */ 71 void *pvData; 72 72 /** Monotonic counter value. */ 73 73 uint64_t cMonotonic; … … 386 386 pObjInfo->BirthTime = *pTime; 387 387 pObjInfo->Attr.fMode = fIsDir 388 ? RTFS_TYPE_DIRECTORY | RTFS_UNIX_ALL_PERMS 389 : RTFS_TYPE_FILE | RTFS_UNIX_ALL_PERMS; 388 ? RTFS_TYPE_DIRECTORY | RTFS_UNIX_ALL_ACCESS_PERMS 389 : RTFS_TYPE_FILE | RTFS_UNIX_IWOTH | RTFS_UNIX_IROTH 390 | RTFS_UNIX_IWGRP | RTFS_UNIX_IRGRP 391 | RTFS_UNIX_IWUSR | RTFS_UNIX_IRUSR; 390 392 pObjInfo->Attr.enmAdditional = enmAddAttr; 391 393 … … 532 534 if (RT_SUCCESS(rc)) 533 535 pThis->offFile = off + cbThisRead; 534 Log6(("rt FsEfiVarStore_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc));536 Log6(("rtEfiVarStoreFile_ReadMem: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc)); 535 537 } 536 538 else … … 551 553 } 552 554 Log6(("rtEfiVarStoreFile_ReadMem: off=%#RX64 cbSeg=%#x -> %Rrc *pcbRead=%#x\n", off, pSgBuf->paSegs[0].cbSeg, rc, *pcbRead)); 555 } 556 557 return rc; 558 } 559 560 561 /** 562 * Writes variable data from the given memory area. 563 * 564 * @returns IPRT status code. 565 * @param pThis The EFI variable file instance. 566 * @param pvData Pointer to the start of the data. 567 * @param cbData Size of the variable data in bytes. 568 * @param off Where to start writing relative from the data start offset. 569 * @param pSgBuf The data to write. 570 * @param pcbWritten Where to return the number of bytes written, optional. 571 */ 572 static int rtEfiVarStoreFile_WriteMem(PRTEFIVARFILE pThis, void *pvData, size_t cbData, 573 RTFOFF off, PCRTSGBUF pSgBuf, size_t *pcbWritten) 574 { 575 int rc = VINF_SUCCESS; 576 size_t cbWrite = pSgBuf->paSegs[0].cbSeg; 577 size_t cbThisWrite = RT_MIN(cbData - off, cbWrite); 578 uint8_t *pbData = (uint8_t *)pvData; 579 if (!pcbWritten) 580 { 581 if (cbThisWrite == cbWrite) 582 memcpy(&pbData[off], pSgBuf->paSegs[0].pvSeg, cbThisWrite); 583 else 584 rc = VERR_EOF; 585 586 if (RT_SUCCESS(rc)) 587 pThis->offFile = off + cbThisWrite; 588 Log6(("rtEfiVarStoreFile_WriteMem: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc)); 589 } 590 else 591 { 592 if ((uint64_t)off >= cbData) 593 { 594 *pcbWritten = 0; 595 rc = VINF_EOF; 596 } 597 else 598 { 599 memcpy(&pbData[off], pSgBuf->paSegs[0].pvSeg, cbThisWrite); 600 /* Return VINF_EOF if beyond end-of-file. */ 601 if (cbThisWrite < cbWrite) 602 rc = VINF_EOF; 603 pThis->offFile = off + cbThisWrite; 604 *pcbWritten = cbThisWrite; 605 } 606 Log6(("rtEfiVarStoreFile_WriteMem: off=%#RX64 cbSeg=%#x -> %Rrc *pcbWritten=%#x\n", off, pSgBuf->paSegs[0].cbSeg, rc, *pcbWritten)); 553 607 } 554 608 … … 616 670 617 671 /** 672 * Ensures that the variable data is available before any modification. 673 * 674 * @returns IPRT status code. 675 * @param pVar The variable instance. 676 */ 677 static int rtEfiVarStore_VarReadData(PRTEFIVAR pVar) 678 { 679 if (RT_LIKELY( !pVar->offVarData 680 || !pVar->cbData)) 681 return VINF_SUCCESS; 682 683 Assert(!pVar->pvData); 684 pVar->pvData = RTMemAlloc(pVar->cbData); 685 if (RT_UNLIKELY(!pVar->pvData)) 686 return VERR_NO_MEMORY; 687 688 PRTEFIVARSTORE pVarStore = pVar->pVarStore; 689 int rc = RTVfsFileReadAt(pVarStore->hVfsBacking, pVar->offVarData, pVar->pvData, pVar->cbData, NULL); 690 if (RT_SUCCESS(rc)) 691 pVar->offVarData = 0; /* Marks the variable data as in memory. */ 692 else 693 { 694 RTMemFree(pVar->pvData); 695 pVar->pvData = NULL; 696 } 697 698 return rc; 699 } 700 701 702 /** 703 * Ensures that the given variable has the given data size. 704 * 705 * @returns IPRT status code. 706 * @retval VERR_DISK_FULL if the new size would exceed the variable storage size. 707 * @param pVar The variable instance. 708 * @param cbData New number of bytes of data for the variable. 709 */ 710 static int rtEfiVarStore_VarEnsureDataSz(PRTEFIVAR pVar, size_t cbData) 711 { 712 PRTEFIVARSTORE pVarStore = pVar->pVarStore; 713 714 if (pVar->cbData == cbData) 715 return VINF_SUCCESS; 716 717 int rc = VINF_SUCCESS; 718 if (cbData < pVar->cbData) 719 { 720 /* Shrink. */ 721 void *pvNew = RTMemRealloc(pVar->pvData, cbData); 722 if (pvNew) 723 { 724 pVar->pvData = pvNew; 725 pVarStore->cbVarData -= pVar->cbData - cbData; 726 pVar->cbData = cbData; 727 } 728 else 729 rc = VERR_NO_MEMORY; 730 } 731 else if (cbData > pVar->cbData) 732 { 733 /* Grow. */ 734 if (pVarStore->cbVarStore - pVarStore->cbVarData >= cbData - pVar->cbData) 735 { 736 void *pvNew = RTMemRealloc(pVar->pvData, cbData); 737 if (pvNew) 738 { 739 pVar->pvData = pvNew; 740 pVarStore->cbVarData += cbData - pVar->cbData; 741 pVar->cbData = cbData; 742 } 743 else 744 rc = VERR_NO_MEMORY; 745 } 746 else 747 rc = VERR_DISK_FULL; 748 } 749 750 return rc; 751 } 752 753 754 /** 618 755 * Flush the variable store to the backing storage. This will remove any 619 756 * deleted variables in the backing storage. … … 626 763 int rc = VINF_SUCCESS; 627 764 uint64_t offCur = pThis->offStoreData; 628 void *pvData = NULL;629 size_t cbData = 0;630 size_t cbDataMax = 0;631 765 632 766 for (uint32_t i = 0; i < pThis->cVars && RT_SUCCESS(rc); i++) … … 642 776 643 777 /* 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. */ 778 rc = rtEfiVarStore_VarReadData(pVar); 666 779 if (RT_SUCCESS(rc)) 667 780 { 781 /* Write out the variable. */ 668 782 EFI_AUTH_VAR_HEADER VarHdr; 669 783 size_t cbName = cwcLen * sizeof(RTUTF16); … … 684 798 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr), pwszName, cbName, NULL); 685 799 if (RT_SUCCESS(rc)) 686 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, p vData,cbData, NULL);800 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, pVar->pvData, pVar->cbData, NULL); 687 801 if (RT_SUCCESS(rc)) 688 802 { 689 offCur += sizeof(VarHdr) + cbName + cbData;803 offCur += sizeof(VarHdr) + cbName + pVar->cbData; 690 804 uint64_t offCurAligned = RT_ALIGN_64(offCur, sizeof(uint16_t)); 691 805 if (offCurAligned > offCur) … … 722 836 } 723 837 724 if (pvData)725 RTMemFree(pvData);726 727 838 return rc; 728 839 } … … 781 892 rc = rtEfiVarStoreFile_ReadMem(pThis, (const uint8_t *)pVar + pThis->pEntry->offObject, pThis->pEntry->cbObject, off, pSgBuf, pcbRead); 782 893 else 783 rc = rtEfiVarStoreFile_ReadFile(pThis, pVar->offVarData, pVar->cbData, off, pSgBuf, pcbRead); 894 { 895 /* Data section. */ 896 if (!pVar->offVarData) 897 rc = rtEfiVarStoreFile_ReadMem(pThis, pVar->pvData, pVar->cbData, off, pSgBuf, pcbRead); 898 else 899 rc = rtEfiVarStoreFile_ReadFile(pThis, pVar->offVarData, pVar->cbData, off, pSgBuf, pcbRead); 900 } 784 901 785 902 return rc; … … 792 909 static DECLCALLBACK(int) rtEfiVarStoreFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten) 793 910 { 794 RT_NOREF(pvThis, off, pSgBuf, fBlocking, pcbWritten); 795 return VERR_WRITE_PROTECT; 911 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 912 PRTEFIVARSTORE pVarStore = pThis->pVarStore; 913 PRTEFIVAR pVar = pThis->pVar; 914 AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3); 915 RT_NOREF(fBlocking); 916 917 if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY) 918 return VERR_WRITE_PROTECT; 919 920 if (off == -1) 921 off = pThis->offFile; 922 else 923 AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3); 924 925 int rc; 926 if (pThis->pEntry->cbObject) /* These can't grow. */ 927 rc = rtEfiVarStoreFile_WriteMem(pThis, (uint8_t *)pVar + pThis->pEntry->offObject, pThis->pEntry->cbObject, 928 off, pSgBuf, pcbWritten); 929 else 930 { 931 /* Writing data section. */ 932 rc = rtEfiVarStore_VarReadData(pVar); 933 if (RT_SUCCESS(rc)) 934 { 935 if (off + pSgBuf->paSegs[0].cbSeg > pVar->cbData) 936 rc = rtEfiVarStore_VarEnsureDataSz(pVar, off + pSgBuf->paSegs[0].cbSeg); 937 if (RT_SUCCESS(rc)) 938 rc = rtEfiVarStoreFile_WriteMem(pThis, pVar->pvData, pVar->cbData, off, pSgBuf, pcbWritten); 939 } 940 } 941 942 return rc; 796 943 } 797 944 … … 899 1046 static DECLCALLBACK(int) rtEfiVarStoreFile_SetSize(void *pvThis, uint64_t cbFile, uint32_t fFlags) 900 1047 { 901 RT_NOREF(pvThis, cbFile, fFlags); 902 return VERR_WRITE_PROTECT; 1048 PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis; 1049 PRTEFIVAR pVar = pThis->pVar; 1050 PRTEFIVARSTORE pVarStore = pThis->pVarStore; 1051 1052 RT_NOREF(fFlags); 1053 1054 if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY) 1055 return VERR_WRITE_PROTECT; 1056 1057 int rc = rtEfiVarStore_VarReadData(pVar); 1058 if (RT_SUCCESS(rc)) 1059 rc = rtEfiVarStore_VarEnsureDataSz(pVar, cbFile); 1060 1061 return rc; 903 1062 } 904 1063 … … 916 1075 917 1076 /** 918 * E XTfile operations.1077 * EFI variable store file operations. 919 1078 */ 920 1079 static const RTVFSFILEOPS g_rtEfiVarStoreFileOps = … … 924 1083 RTVFSOBJOPS_VERSION, 925 1084 RTVFSOBJTYPE_FILE, 926 "E FiVarStore File",1085 "EfiVarStore File", 927 1086 rtEfiVarStoreFile_Close, 928 1087 rtEfiVarStoreFile_QueryInfo, … … 1112 1271 */ 1113 1272 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 1114 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE) 1273 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 1274 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 1115 1275 { /* likely */ } 1116 1276 else … … 1280 1440 LogFlowFunc(("\n")); 1281 1441 1282 pThis->idxNext 1442 pThis->idxNext = 0; 1283 1443 return VINF_SUCCESS; 1284 1444 } … … 1788 1948 PRTEFIVAR pVar = &pThis->paVars[pThis->cVars++]; 1789 1949 pVar->pVarStore = pThis; 1790 pVar->offVarHdr = offVar;1791 1950 pVar->offVarData = offVar + sizeof(VarHdr) + RT_LE2H_U32(VarHdr.cbName); 1792 1951 pVar->fAttr = RT_LE2H_U32(VarHdr.fAttr); … … 1794 1953 pVar->idPubKey = RT_LE2H_U32(VarHdr.idPubKey); 1795 1954 pVar->cbData = RT_LE2H_U32(VarHdr.cbData); 1955 pVar->pvData = NULL; 1796 1956 memcpy(&pVar->EfiTimestamp, &VarHdr.Timestamp, sizeof(VarHdr.Timestamp)); 1797 1957
Note:
See TracChangeset
for help on using the changeset viewer.