Changeset 90133 in vbox
- Timestamp:
- Jul 9, 2021 3:28:59 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp
r90126 r90133 78 78 /** Attributes for the variable. */ 79 79 uint32_t fAttr; 80 /** Flag whether the variable was deleted. */ 81 bool fDeleted; 80 82 /** Name of the variable. */ 81 83 char *pszName; … … 773 775 PRTEFIVAR pVar = &pThis->paVars[i]; 774 776 775 rc = RTStrToUtf16Ex(pVar->pszName, RTSTR_MAX, &pwszName, 0, &cwcLen); 776 if (RT_SUCCESS(rc)) 777 { 778 cwcLen++; /* Include the terminator. */ 779 780 /* Read in the data of the variable if it exists. */ 781 rc = rtEfiVarStore_VarReadData(pVar); 777 if (!pVar->fDeleted) 778 { 779 rc = RTStrToUtf16Ex(pVar->pszName, RTSTR_MAX, &pwszName, 0, &cwcLen); 782 780 if (RT_SUCCESS(rc)) 783 781 { 784 /* Write out the variable. */ 785 EFI_AUTH_VAR_HEADER VarHdr; 786 size_t cbName = cwcLen * sizeof(RTUTF16); 787 788 VarHdr.u16StartId = RT_H2LE_U16(EFI_AUTH_VAR_HEADER_START); 789 VarHdr.bState = EFI_AUTH_VAR_HEADER_STATE_ADDED; 790 VarHdr.bRsvd = 0; 791 VarHdr.fAttr = RT_H2LE_U32(pVar->fAttr); 792 VarHdr.cMonotonic = RT_H2LE_U64(pVar->cMonotonic); 793 VarHdr.idPubKey = RT_H2LE_U32(pVar->idPubKey); 794 VarHdr.cbName = RT_H2LE_U32((uint32_t)cbName); 795 VarHdr.cbData = RT_H2LE_U32(pVar->cbData); 796 RTEfiGuidFromUuid(&VarHdr.GuidVendor, &pVar->Uuid); 797 memcpy(&VarHdr.Timestamp, &pVar->EfiTimestamp, sizeof(pVar->EfiTimestamp)); 798 799 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &VarHdr, sizeof(VarHdr), NULL); 800 if (RT_SUCCESS(rc)) 801 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr), pwszName, cbName, NULL); 802 if (RT_SUCCESS(rc)) 803 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, pVar->pvData, pVar->cbData, NULL); 782 cwcLen++; /* Include the terminator. */ 783 784 /* Read in the data of the variable if it exists. */ 785 rc = rtEfiVarStore_VarReadData(pVar); 804 786 if (RT_SUCCESS(rc)) 805 787 { 806 offCur += sizeof(VarHdr) + cbName + pVar->cbData; 807 uint64_t offCurAligned = RT_ALIGN_64(offCur, sizeof(uint16_t)); 808 if (offCurAligned > offCur) 788 /* Write out the variable. */ 789 EFI_AUTH_VAR_HEADER VarHdr; 790 size_t cbName = cwcLen * sizeof(RTUTF16); 791 792 VarHdr.u16StartId = RT_H2LE_U16(EFI_AUTH_VAR_HEADER_START); 793 VarHdr.bState = EFI_AUTH_VAR_HEADER_STATE_ADDED; 794 VarHdr.bRsvd = 0; 795 VarHdr.fAttr = RT_H2LE_U32(pVar->fAttr); 796 VarHdr.cMonotonic = RT_H2LE_U64(pVar->cMonotonic); 797 VarHdr.idPubKey = RT_H2LE_U32(pVar->idPubKey); 798 VarHdr.cbName = RT_H2LE_U32((uint32_t)cbName); 799 VarHdr.cbData = RT_H2LE_U32(pVar->cbData); 800 RTEfiGuidFromUuid(&VarHdr.GuidVendor, &pVar->Uuid); 801 memcpy(&VarHdr.Timestamp, &pVar->EfiTimestamp, sizeof(pVar->EfiTimestamp)); 802 803 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &VarHdr, sizeof(VarHdr), NULL); 804 if (RT_SUCCESS(rc)) 805 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr), pwszName, cbName, NULL); 806 if (RT_SUCCESS(rc)) 807 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, pVar->pvData, pVar->cbData, NULL); 808 if (RT_SUCCESS(rc)) 809 809 { 810 /* Should be at most 1 byte to align the next variable to a 16bit boundary. */ 811 Assert(offCurAligned - offCur == 1); 812 uint8_t bFill = 0xff; 813 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &bFill, sizeof(bFill), NULL); 810 offCur += sizeof(VarHdr) + cbName + pVar->cbData; 811 uint64_t offCurAligned = RT_ALIGN_64(offCur, sizeof(uint16_t)); 812 if (offCurAligned > offCur) 813 { 814 /* Should be at most 1 byte to align the next variable to a 16bit boundary. */ 815 Assert(offCurAligned - offCur == 1); 816 uint8_t bFill = 0xff; 817 rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &bFill, sizeof(bFill), NULL); 818 } 819 820 offCur = offCurAligned; 814 821 } 815 816 offCur = offCurAligned;817 822 } 823 824 RTUtf16Free(pwszName); 818 825 } 819 820 RTUtf16Free(pwszName);821 826 } 822 827 } … … 840 845 841 846 return rc; 847 } 848 849 850 /** 851 * Tries to find a variable with the given name. 852 * 853 * @returns Pointer to the variable if found or NULL otherwise. 854 * @param pThis The variable store instance. 855 * @param pszName Name of the variable to look for. 856 * @param pidVar Where to store the index of the variable, optional. 857 */ 858 static PRTEFIVAR rtEfiVarStore_VarGet(PRTEFIVARSTORE pThis, const char *pszName, uint32_t *pidVar) 859 { 860 for (uint32_t i = 0; i < pThis->cVars; i++) 861 if ( !pThis->paVars[i].fDeleted 862 && !strcmp(pszName, pThis->paVars[i].pszName)) 863 { 864 if (pidVar) 865 *pidVar = i; 866 return &pThis->paVars[i]; 867 } 868 869 return NULL; 870 } 871 872 873 /** 874 * Maybe grows the array of variables to hold more entries. 875 * 876 * @returns IPRT status code. 877 * @param pThis The variable store instance. 878 */ 879 static int rtEfiVarStore_VarMaybeGrowEntries(PRTEFIVARSTORE pThis) 880 { 881 if (pThis->cVars == pThis->cVarsMax) 882 { 883 /* Grow the variable array. */ 884 uint32_t cVarsMaxNew = pThis->cVarsMax + 10; 885 PRTEFIVAR paVarsNew = (PRTEFIVAR)RTMemRealloc(pThis->paVars, cVarsMaxNew * sizeof(RTEFIVAR)); 886 if (!paVarsNew) 887 return VERR_NO_MEMORY; 888 889 pThis->paVars = paVarsNew; 890 pThis->cVarsMax = cVarsMaxNew; 891 } 892 893 return VINF_SUCCESS; 894 } 895 896 897 /** 898 * Add a variable with the given name. 899 * 900 * @returns Pointer to the entry or NULL if out of memory. 901 * @param pThis The variable store instance. 902 * @param pszName Name of the variable to add. 903 * @param pidVar Where to store the variable index on success, optional 904 */ 905 static PRTEFIVAR rtEfiVarStore_VarAdd(PRTEFIVARSTORE pThis, const char *pszName, uint32_t *pidVar) 906 { 907 Assert(!rtEfiVarStore_VarGet(pThis, pszName, NULL)); 908 909 int rc = rtEfiVarStore_VarMaybeGrowEntries(pThis); 910 if (RT_SUCCESS(rc)) 911 { 912 PRTEFIVAR pVar = &pThis->paVars[pThis->cVars]; 913 RT_ZERO(*pVar); 914 915 pVar->pszName = RTStrDup(pszName); 916 if (pVar->pszName) 917 { 918 pVar->pVarStore = pThis; 919 pVar->offVarData = 0; 920 pVar->fDeleted = false; 921 RTTimeNow(&pVar->Time); 922 923 if (pidVar) 924 *pidVar = pThis->cVars; 925 pThis->cVars++; 926 return pVar; 927 } 928 } 929 930 return NULL; 931 } 932 933 934 /** 935 * Delete the given variable. 936 * 937 * @returns IPRT status code. 938 * @param pThis The variable store instance. 939 * @param pVar The variable. 940 */ 941 static int rtEfiVarStore_VarDel(PRTEFIVARSTORE pThis, PRTEFIVAR pVar) 942 { 943 pVar->fDeleted = true; 944 if (pVar->pvData) 945 RTMemFree(pVar->pvData); 946 pVar->pvData = NULL; 947 pThis->cbVarData -= sizeof(EFI_AUTH_VAR_HEADER) + pVar->cbData; 948 /** @todo Delete from GUID entry. */ 949 return VINF_SUCCESS; 950 } 951 952 953 /** 954 * Delete the variable with the given index. 955 * 956 * @returns IPRT status code. 957 * @param pThis The variable store instance. 958 * @param idVar The variable index. 959 */ 960 static int rtEfiVarStore_VarDelById(PRTEFIVARSTORE pThis, uint32_t idVar) 961 { 962 return rtEfiVarStore_VarDel(pThis, &pThis->paVars[idVar]); 963 } 964 965 966 /** 967 * Delete the variable with the given name. 968 * 969 * @returns IPRT status code. 970 * @param pThis The variable store instance. 971 * @param pszName Name of the variable to delete. 972 */ 973 static int rtEfiVarStore_VarDelByName(PRTEFIVARSTORE pThis, const char *pszName) 974 { 975 PRTEFIVAR pVar = rtEfiVarStore_VarGet(pThis, pszName, NULL); 976 if (pVar) 977 return rtEfiVarStore_VarDel(pThis, pVar); 978 979 return VERR_FILE_NOT_FOUND; 842 980 } 843 981 … … 1302 1440 { 1303 1441 /* Look for the name. */ 1304 for (uint32_t i = 0; i < pVarStore->cVars; i++) 1305 if (!strcmp(pszEntry, pVarStore->paVars[i].pszName)) 1306 { 1307 if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW) 1308 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW_ENTRY, 1309 NULL /*pGuid*/, i /*idVar*/, phVfsObj); 1310 else 1311 return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[i], 1312 &g_aRawFiles[RTEFIVARSTORE_FILE_ENTRY_DATA], phVfsObj); 1313 } 1442 uint32_t idVar = 0; 1443 PRTEFIVAR pVar = rtEfiVarStore_VarGet(pVarStore, pszEntry, &idVar); 1444 if (pVar) 1445 { 1446 if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW) 1447 return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW_ENTRY, 1448 NULL /*pGuid*/, idVar, phVfsObj); 1449 else 1450 return rtEfiVarStore_NewFile(pVarStore, fOpen, pVar, 1451 &g_aRawFiles[RTEFIVARSTORE_FILE_ENTRY_DATA], phVfsObj); 1452 } 1314 1453 1315 1454 rc = VERR_FILE_NOT_FOUND; … … 1364 1503 LogFlowFunc(("\n")); 1365 1504 1366 RT_NOREF( pszSubDir,fMode, phVfsDir);1505 RT_NOREF(fMode, phVfsDir); 1367 1506 1368 1507 if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY) 1369 1508 return VERR_WRITE_PROTECT; 1370 1509 1371 /* We support creating directories only for GUIDs. */ 1372 if (pThis->enmType != RTEFIVARSTOREDIRTYPE_BY_GUID) 1373 return VERR_NOT_SUPPORTED; 1374 1375 RTUUID Uuid; 1376 int rc = RTUuidFromStr(&Uuid, pszSubDir); 1377 if (RT_FAILURE(rc)) 1378 return VERR_NOT_SUPPORTED; 1379 1380 PRTEFIGUID pGuid = rtEfiVarStore_GetGuid(pVarStore, &Uuid); 1381 if (pGuid) 1382 return VERR_ALREADY_EXISTS; 1383 1384 pGuid = rtEfiVarStore_AddGuid(pVarStore, &Uuid); 1385 if (!pGuid) 1386 return VERR_NO_MEMORY; 1387 1388 return VINF_SUCCESS; 1510 /* We support creating directories only for GUIDs and RAW variable entries. */ 1511 int rc = VINF_SUCCESS; 1512 if (pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_GUID) 1513 { 1514 RTUUID Uuid; 1515 rc = RTUuidFromStr(&Uuid, pszSubDir); 1516 if (RT_FAILURE(rc)) 1517 return VERR_NOT_SUPPORTED; 1518 1519 PRTEFIGUID pGuid = rtEfiVarStore_GetGuid(pVarStore, &Uuid); 1520 if (pGuid) 1521 return VERR_ALREADY_EXISTS; 1522 1523 pGuid = rtEfiVarStore_AddGuid(pVarStore, &Uuid); 1524 if (!pGuid) 1525 return VERR_NO_MEMORY; 1526 } 1527 else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW) 1528 { 1529 PRTEFIVAR pVar = rtEfiVarStore_VarGet(pVarStore, pszSubDir, NULL /*pidVar*/); 1530 if (!pVar) 1531 { 1532 if (sizeof(EFI_AUTH_VAR_HEADER) < pVarStore->cbVarStore - pVarStore->cbVarData) 1533 { 1534 uint32_t idVar = 0; 1535 pVar = rtEfiVarStore_VarAdd(pVarStore, pszSubDir, &idVar); 1536 if (pVar) 1537 pVarStore->cbVarData += sizeof(EFI_AUTH_VAR_HEADER); 1538 else 1539 rc = VERR_NO_MEMORY; 1540 } 1541 else 1542 rc = VERR_DISK_FULL; 1543 } 1544 else 1545 rc = VERR_ALREADY_EXISTS; 1546 } 1547 else 1548 rc = VERR_NOT_SUPPORTED; 1549 1550 return rc; 1389 1551 } 1390 1552 … … 1418 1580 static DECLCALLBACK(int) rtEfiVarStoreDir_UnlinkEntry(void *pvThis, const char *pszEntry, RTFMODE fType) 1419 1581 { 1420 RT_NOREF(pvThis, pszEntry, fType); 1582 PRTEFIVARSTOREDIR pThis = (PRTEFIVARSTOREDIR)pvThis; 1583 PRTEFIVARSTORE pVarStore = pThis->pVarStore; 1421 1584 LogFlowFunc(("\n")); 1422 return VERR_WRITE_PROTECT; 1585 1586 RT_NOREF(fType); 1587 1588 if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY) 1589 return VERR_WRITE_PROTECT; 1590 1591 if ( pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW 1592 || pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_NAME 1593 || pThis->enmType == RTEFIVARSTOREDIRTYPE_GUID) 1594 return rtEfiVarStore_VarDelByName(pVarStore, pszEntry); 1595 else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_GUID) 1596 { 1597 /* Look for the name. */ 1598 for (uint32_t i = 0; i < pVarStore->cGuids; i++) 1599 { 1600 PRTEFIGUID pGuid = &pVarStore->paGuids[i]; 1601 char szUuid[RTUUID_STR_LENGTH]; 1602 int rc = RTUuidToStr(&pGuid->Uuid, szUuid, sizeof(szUuid)); 1603 AssertRC(rc); RT_NOREF(rc); 1604 1605 if (!strcmp(pszEntry, szUuid)) 1606 { 1607 for (uint32_t iVar = 0; iVar < pGuid->cVars; iVar++) 1608 rtEfiVarStore_VarDelById(pVarStore, pGuid->paidxVars[iVar]); 1609 1610 if (pGuid->paidxVars) 1611 RTMemFree(pGuid->paidxVars); 1612 pGuid->paidxVars = NULL; 1613 pGuid->cVars = 0; 1614 pGuid->cVarsMax = 0; 1615 RTUuidClear(&pGuid->Uuid); 1616 return VINF_SUCCESS; 1617 } 1618 } 1619 1620 return VERR_FILE_NOT_FOUND; 1621 } 1622 1623 return VERR_NOT_SUPPORTED; 1423 1624 } 1424 1625 … … 1696 1897 PRTEFIGUID pGuid = &pThis->paGuids[i]; 1697 1898 1698 AssertPtr(pGuid->paidxVars); 1699 RTMemFree(pGuid->paidxVars); 1700 pGuid->paidxVars = NULL; 1899 if (pGuid->paidxVars) 1900 { 1901 RTMemFree(pGuid->paidxVars); 1902 pGuid->paidxVars = NULL; 1903 } 1701 1904 } 1702 1905 … … 1937 2140 1938 2141 Log2(("Variable name '%ls'\n", &awchName[0])); 1939 if (pThis->cVars == pThis->cVarsMax) 1940 { 1941 /* Grow the variable array. */ 1942 uint32_t cVarsMaxNew = pThis->cVarsMax + 10; 1943 PRTEFIVAR paVarsNew = (PRTEFIVAR)RTMemRealloc(pThis->paVars, cVarsMaxNew * sizeof(RTEFIVAR)); 1944 if (!paVarsNew) 1945 return VERR_NO_MEMORY; 1946 1947 pThis->paVars = paVarsNew; 1948 pThis->cVarsMax = cVarsMaxNew; 1949 } 2142 rc = rtEfiVarStore_VarMaybeGrowEntries(pThis); 2143 if (RT_FAILURE(rc)) 2144 return rc; 1950 2145 1951 2146 PRTEFIVAR pVar = &pThis->paVars[pThis->cVars++]; … … 1957 2152 pVar->cbData = RT_LE2H_U32(VarHdr.cbData); 1958 2153 pVar->pvData = NULL; 2154 pVar->fDeleted = false; 1959 2155 memcpy(&pVar->EfiTimestamp, &VarHdr.Timestamp, sizeof(VarHdr.Timestamp)); 1960 2156
Note:
See TracChangeset
for help on using the changeset viewer.