VirtualBox

Changeset 90133 in vbox


Ignore:
Timestamp:
Jul 9, 2021 3:28:59 PM (4 years ago)
Author:
vboxsync
Message:

Runtime/efivarstorevfs.cpp: Some basic variable creation and deletion code (incomplete), bugref:9580

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp

    r90126 r90133  
    7878    /** Attributes for the variable. */
    7979    uint32_t            fAttr;
     80    /** Flag whether the variable was deleted. */
     81    bool                fDeleted;
    8082    /** Name of the variable. */
    8183    char                *pszName;
     
    773775        PRTEFIVAR pVar = &pThis->paVars[i];
    774776
    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);
    782780            if (RT_SUCCESS(rc))
    783781            {
    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);
    804786                if (RT_SUCCESS(rc))
    805787                {
    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))
    809809                    {
    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;
    814821                    }
    815 
    816                     offCur = offCurAligned;
    817822                }
     823
     824                RTUtf16Free(pwszName);
    818825            }
    819 
    820             RTUtf16Free(pwszName);
    821826        }
    822827    }
     
    840845
    841846    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 */
     858static 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 */
     879static 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 */
     905static 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 */
     941static 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 */
     960static 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 */
     973static 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;
    842980}
    843981
     
    13021440        {
    13031441            /* 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            }
    13141453
    13151454            rc = VERR_FILE_NOT_FOUND;
     
    13641503    LogFlowFunc(("\n"));
    13651504
    1366     RT_NOREF(pszSubDir, fMode, phVfsDir);
     1505    RT_NOREF(fMode, phVfsDir);
    13671506
    13681507    if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY)
    13691508        return VERR_WRITE_PROTECT;
    13701509
    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;
    13891551}
    13901552
     
    14181580static DECLCALLBACK(int) rtEfiVarStoreDir_UnlinkEntry(void *pvThis, const char *pszEntry, RTFMODE fType)
    14191581{
    1420     RT_NOREF(pvThis, pszEntry, fType);
     1582    PRTEFIVARSTOREDIR pThis     = (PRTEFIVARSTOREDIR)pvThis;
     1583    PRTEFIVARSTORE    pVarStore = pThis->pVarStore;
    14211584    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;
    14231624}
    14241625
     
    16961897            PRTEFIGUID pGuid = &pThis->paGuids[i];
    16971898
    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            }
    17011904        }
    17021905
     
    19372140
    19382141    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;
    19502145
    19512146    PRTEFIVAR pVar = &pThis->paVars[pThis->cVars++];
     
    19572152    pVar->cbData     = RT_LE2H_U32(VarHdr.cbData);
    19582153    pVar->pvData     = NULL;
     2154    pVar->fDeleted   = false;
    19592155    memcpy(&pVar->EfiTimestamp, &VarHdr.Timestamp, sizeof(VarHdr.Timestamp));
    19602156
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette