VirtualBox

Ignore:
Timestamp:
Jun 21, 2017 12:48:19 PM (7 years ago)
Author:
vboxsync
Message:

IPRT: More ISO maker code (import related).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67515 r67538  
    9393    ( RT_UOFFSETOF(ISO9660PATHREC, achDirId[(a_cbNameInDirRec) + ((a_cbNameInDirRec) & 1)]) )
    9494
    95 
    96 /** No validation entry in the boot catalog. */
    97 #define VERR_ISOMK_BOOT_CAT_NO_VALIDATION_ENTRY                 (-24900)
    98 /** No default entry in the boot catalog. */
    99 #define VERR_ISOMK_BOOT_CAT_NO_DEFAULT_ENTRY                    (-24901)
    100 /** Expected section header. */
    101 #define VERR_ISOMK_BOOT_CAT_EXPECTED_SECTION_HEADER             (-24902)
    102 /** Entry in a boot catalog section is empty. */
    103 #define VERR_ISOMK_BOOT_CAT_EMPTY_ENTRY                         (-24903)
    104 /** Entry in a boot catalog section is another section. */
    105 #define VERR_ISOMK_BOOT_CAT_INVALID_SECTION_SIZE                (-24904)
    106 /** Unsectioned boot catalog entry. */
    107 #define VERR_ISOMK_BOOT_CAT_ERRATIC_ENTRY                       (-24905)
    10895
    10996
     
    23602347{
    23612348    /*
     2349     * Don't allow removing trans.tbl files and the boot catalog.
     2350     */
     2351    if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE)
     2352    {
     2353        PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj;
     2354        AssertReturn(pFile->enmSrcType != RTFSISOMAKERSRCTYPE_TRANS_TBL, VERR_ACCESS_DENIED);
     2355        AssertReturn(pFile != pThis->pBootCatFile, VERR_ACCESS_DENIED);
     2356    }
     2357
     2358    /*
    23622359     * Remove the object from all name spaces.
    23632360     */
     
    31513148
    31523149/**
     3150 * Sets the boot catalog backing file.
     3151 *
     3152 * The content of the given file will be discarded and replaced with the boot
     3153 * catalog, the naming and file attributes (other than size) will be retained.
     3154 *
     3155 * This API exists mainly to assist when importing ISOs.
     3156 *
     3157 * @returns IPRT status code.
     3158 * @param   hIsoMaker           The ISO maker handle.
     3159 * @param   idxObj              The configuration index of the file.
     3160 */
     3161RTDECL(int) RTFsIsoMakerBootCatSetFile(RTFSISOMAKER hIsoMaker, uint32_t idxObj)
     3162{
     3163    /*
     3164     * Validate and translate input.
     3165     */
     3166    PRTFSISOMAKERINT pThis = hIsoMaker;
     3167    RTFSISOMAKER_ASSERT_VALID_HANDLE_RET(pThis);
     3168
     3169    PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj);
     3170    AssertReturn(pObj, VERR_OUT_OF_RANGE);
     3171    AssertReturn(pObj->enmType == RTFSISOMAKEROBJTYPE_FILE, VERR_WRONG_TYPE);
     3172    PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj;
     3173    AssertReturn(   pFile->enmSrcType == RTFSISOMAKERSRCTYPE_PATH
     3174                 || pFile->enmSrcType == RTFSISOMAKERSRCTYPE_COMMON
     3175                 || pFile->enmSrcType == RTFSISOMAKERSRCTYPE_VFS_FILE,
     3176                 VERR_WRONG_TYPE);
     3177
     3178    /*
     3179     * To reduce the possible combinations here, make sure there is a boot cat
     3180     * file that we're "replacing".
     3181     */
     3182    int rc = rtFsIsoMakerEnsureBootCatFile(pThis);
     3183    if (RT_SUCCESS(rc))
     3184    {
     3185        /*
     3186         * Grab a reference to the boot cat memory VFS so we can destroy it
     3187         * later using regular destructors.
     3188         */
     3189        PRTFSISOMAKERFILE pOldFile = pThis->pBootCatFile;
     3190        RTVFSFILE         hVfsFile = pOldFile->u.hVfsFile;
     3191        uint32_t          cRefs    = RTVfsFileRetain(hVfsFile);
     3192        if (cRefs != UINT32_MAX)
     3193        {
     3194            /*
     3195             * Try remove the existing boot file.
     3196             */
     3197            pOldFile->Core.cNotOrphan--;
     3198            pThis->pBootCatFile = NULL;
     3199            rc = rtFsIsoMakerObjRemoveWorker(pThis, &pOldFile->Core);
     3200            if (RT_SUCCESS(rc))
     3201            {
     3202                /*
     3203                 * Just morph pFile into a boot catalog file.
     3204                 */
     3205                if (pFile->enmSrcType)
     3206                {
     3207                    RTVfsFileRelease(pFile->u.hVfsFile);
     3208                    pFile->u.hVfsFile = NIL_RTVFSFILE;
     3209                }
     3210
     3211                pThis->cbData -= RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE);
     3212                pFile->cbData     = 0;
     3213                pFile->Core.cNotOrphan++;
     3214                pFile->enmSrcType = RTFSISOMAKERSRCTYPE_VFS_FILE;
     3215                pFile->u.hVfsFile = hVfsFile;
     3216
     3217                pThis->pBootCatFile = pFile;
     3218
     3219                return VINF_SUCCESS;
     3220            }
     3221
     3222            pThis->pBootCatFile = pOldFile;
     3223            pOldFile->Core.cNotOrphan++;
     3224            RTVfsFileRelease(hVfsFile);
     3225        }
     3226        else
     3227            rc = VERR_INTERNAL_ERROR_2;
     3228    }
     3229    return rc;
     3230}
     3231
     3232
     3233/**
    31533234 * Set the validation entry of the boot catalog (this is the first entry).
    31543235 *
     
    32403321 *                              mode segment number).
    32413322 * @param   cSectorsToLoad      Number of emulated sectors to load.
     3323 * @param   bSelCritType        The selection criteria type, if none pass
     3324 *                              ISO9660_ELTORITO_SEL_CRIT_TYPE_NONE.
     3325 * @param   pvSelCritData       Pointer to the selection criteria data.
     3326 * @param   cbSelCritData       Size of the selection criteria data.
    32423327 */
    32433328RTDECL(int) RTFsIsoMakerBootCatSetSectionEntry(RTFSISOMAKER hIsoMaker, uint32_t idxBootCat, uint32_t idxImageObj,
    32443329                                               uint8_t bBootMediaType, uint8_t bSystemType, bool fBootable,
    3245                                                uint16_t uLoadSeg, uint16_t cSectorsToLoad)
     3330                                               uint16_t uLoadSeg, uint16_t cSectorsToLoad,
     3331                                               uint8_t bSelCritType, void const *pvSelCritData, size_t cbSelCritData)
    32463332{
    32473333    /*
     
    32593345    AssertReturn(idxBootCat != 0 && idxBootCat != 2 && idxBootCat < RT_ELEMENTS(pThis->aBootCatEntries) - 1U, VERR_OUT_OF_RANGE);
    32603346
     3347    size_t cExtEntries = 0;
     3348    if (bSelCritType == ISO9660_ELTORITO_SEL_CRIT_TYPE_NONE)
     3349        AssertReturn(cbSelCritData == 0, VERR_INVALID_PARAMETER);
     3350    else
     3351    {
     3352        AssertReturn(idxBootCat > 2, VERR_INVALID_PARAMETER);
     3353        if (cbSelCritData > 0)
     3354        {
     3355            AssertPtrReturn(pvSelCritData, VERR_INVALID_POINTER);
     3356
     3357            if (cbSelCritData <= RT_SIZEOFMEMB(ISO9660ELTORITOSECTIONENTRY, abSelectionCriteria))
     3358                cExtEntries = 0;
     3359            else
     3360            {
     3361                cExtEntries = (cbSelCritData - RT_SIZEOFMEMB(ISO9660ELTORITOSECTIONENTRY, abSelectionCriteria)
     3362                               + RT_SIZEOFMEMB(ISO9660ELTORITOSECTIONENTRYEXT, abSelectionCriteria) - 1)
     3363                            / RT_SIZEOFMEMB(ISO9660ELTORITOSECTIONENTRYEXT, abSelectionCriteria);
     3364                AssertReturn(cExtEntries + 1 < RT_ELEMENTS(pThis->aBootCatEntries) - 1, VERR_TOO_MUCH_DATA);
     3365            }
     3366        }
     3367    }
     3368
    32613369    /*
    32623370     * Make sure we've got a boot file.
     
    32683376         * Construct the entry.
    32693377         */
    3270         ISO9660ELTORITOSECTIONENTRY Entry;
    3271         Entry.bBootIndicator            = fBootable ? ISO9660_ELTORITO_BOOT_INDICATOR_BOOTABLE
    3272                                         :             ISO9660_ELTORITO_BOOT_INDICATOR_NOT_BOOTABLE;
    3273         Entry.bBootMediaType            = bBootMediaType;
    3274         Entry.uLoadSeg                  = RT_H2LE_U16(uLoadSeg);
    3275         Entry.bSystemType               = bSystemType;
    3276         Entry.bUnused                   = 0;
    3277         Entry.cEmulatedSectorsToLoad    = RT_H2LE_U16(cSectorsToLoad);
    3278         Entry.offBootImage              = 0;
    3279         Entry.bSelectionCriteriaType    = ISO9660_ELTORITO_SEL_CRIT_TYPE_NONE;
    3280         RT_ZERO(Entry.abSelectionCriteria);
     3378        union
     3379        {
     3380            ISO9660ELTORITOSECTIONENTRY     Entry;
     3381            ISO9660ELTORITOSECTIONENTRYEXT  ExtEntry;
     3382        } u;
     3383        u.Entry.bBootIndicator            = fBootable ? ISO9660_ELTORITO_BOOT_INDICATOR_BOOTABLE
     3384                                          :             ISO9660_ELTORITO_BOOT_INDICATOR_NOT_BOOTABLE;
     3385        u.Entry.bBootMediaType            = bBootMediaType;
     3386        u.Entry.uLoadSeg                  = RT_H2LE_U16(uLoadSeg);
     3387        u.Entry.bSystemType               = cExtEntries == 0
     3388                                          ? bSystemType & ~ISO9660_ELTORITO_BOOT_MEDIA_F_CONTINUATION
     3389                                          : bSystemType | ISO9660_ELTORITO_BOOT_MEDIA_F_CONTINUATION;
     3390        u.Entry.bUnused                   = 0;
     3391        u.Entry.cEmulatedSectorsToLoad    = RT_H2LE_U16(cSectorsToLoad);
     3392        u.Entry.offBootImage              = 0;
     3393        u.Entry.bSelectionCriteriaType    = bSelCritType;
     3394        RT_ZERO(u.Entry.abSelectionCriteria);
     3395        if (cbSelCritData > 0)
     3396            memcpy(u.Entry.abSelectionCriteria, pvSelCritData, RT_MIN(cbSelCritData, sizeof(u.Entry.abSelectionCriteria)));
    32813397
    32823398        /*
    32833399         * Write it and update our internal tracker.
    32843400         */
    3285         rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, 32 * idxBootCat, &Entry, sizeof(Entry), NULL);
     3401        rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, ISO9660_ELTORITO_ENTRY_SIZE * idxBootCat,
     3402                              &u.Entry, sizeof(u.Entry), NULL);
    32863403        if (RT_SUCCESS(rc))
    32873404        {
     
    32943411            }
    32953412
    3296             pThis->aBootCatEntries[idxBootCat].bType    = Entry.bBootIndicator;
     3413            pThis->aBootCatEntries[idxBootCat].bType    = u.Entry.bBootIndicator;
    32973414            pThis->aBootCatEntries[idxBootCat].cEntries = 1;
     3415        }
     3416
     3417        /*
     3418         * Do add further extension entries with selection criteria.
     3419         */
     3420        if (cExtEntries)
     3421        {
     3422            uint8_t const *pbSrc = (uint8_t const *)pvSelCritData;
     3423            size_t         cbSrc = cbSelCritData;
     3424            pbSrc += sizeof(u.Entry.abSelectionCriteria);
     3425            cbSrc -= sizeof(u.Entry.abSelectionCriteria);
     3426
     3427            while (cbSrc > 0)
     3428            {
     3429                u.ExtEntry.bExtensionId = ISO9660_ELTORITO_SECTION_ENTRY_EXT_ID;
     3430                if (cbSrc > sizeof(u.ExtEntry.abSelectionCriteria))
     3431                {
     3432                    u.ExtEntry.fFlags = ISO9660_ELTORITO_SECTION_ENTRY_EXT_F_MORE;
     3433                    memcpy(u.ExtEntry.abSelectionCriteria, pbSrc, sizeof(u.ExtEntry.abSelectionCriteria));
     3434                    pbSrc += sizeof(u.ExtEntry.abSelectionCriteria);
     3435                    cbSrc -= sizeof(u.ExtEntry.abSelectionCriteria);
     3436                }
     3437                else
     3438                {
     3439                    u.ExtEntry.fFlags = 0;
     3440                    RT_ZERO(u.ExtEntry.abSelectionCriteria);
     3441                    memcpy(u.ExtEntry.abSelectionCriteria, pbSrc, cbSrc);
     3442                    cbSrc = 0;
     3443                }
     3444
     3445                idxBootCat++;
     3446                rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, ISO9660_ELTORITO_ENTRY_SIZE * idxBootCat,
     3447                                      &u.Entry, sizeof(u.Entry), NULL);
     3448                if (RT_FAILURE(rc))
     3449                    break;
     3450
     3451                /* update the internal tracker. */
     3452                if (pThis->aBootCatEntries[idxBootCat].pBootFile)
     3453                {
     3454                    pThis->aBootCatEntries[idxBootCat].pBootFile->Core.cNotOrphan--;
     3455                    pThis->aBootCatEntries[idxBootCat].pBootFile = NULL;
     3456                }
     3457
     3458                pThis->aBootCatEntries[idxBootCat].bType    = ISO9660_ELTORITO_SECTION_ENTRY_EXT_ID;
     3459                pThis->aBootCatEntries[idxBootCat].cEntries = 1;
     3460            }
    32983461        }
    32993462    }
     
    33573520         * Write the entry and update our internal tracker.
    33583521         */
    3359         rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, 32 * idxBootCat, &Entry, sizeof(Entry), NULL);
     3522        rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, ISO9660_ELTORITO_ENTRY_SIZE * idxBootCat,
     3523                              &Entry, sizeof(Entry), NULL);
    33603524        if (RT_SUCCESS(rc))
    33613525        {
     
    34753639     * Fixate the size of the boot catalog file.
    34763640     */
    3477     pThis->pBootCatFile->cbData = cEntriesInFile * 32;
    3478     pThis->cbData  += RT_ALIGN_32(cEntriesInFile * 32, RTFSISOMAKER_SECTOR_SIZE);
     3641    pThis->pBootCatFile->cbData = cEntriesInFile * ISO9660_ELTORITO_ENTRY_SIZE;
     3642    pThis->cbData  += RT_ALIGN_32(cEntriesInFile * ISO9660_ELTORITO_ENTRY_SIZE, RTFSISOMAKER_SECTOR_SIZE);
    34793643
    34803644    /*
     
    35333697            off = RT_H2LE_U32(off);
    35343698            int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile,
    3535                                       i * 32 + RT_UOFFSETOF(ISO9660ELTORITOSECTIONENTRY, offBootImage),
     3699                                      i * ISO9660_ELTORITO_ENTRY_SIZE + RT_UOFFSETOF(ISO9660ELTORITOSECTIONENTRY, offBootImage),
    35363700                                      &off, sizeof(off), NULL /*pcbWritten*/);
    35373701            AssertRCReturn(rc, rc);
     
    35483712    Entry.cEntries    = 0;
    35493713    RT_ZERO(Entry.achSectionId);
    3550     int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, cEntries * 32, &Entry, sizeof(Entry), NULL /*pcbWritten*/);
     3714    int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, cEntries * ISO9660_ELTORITO_ENTRY_SIZE,
     3715                              &Entry, sizeof(Entry), NULL /*pcbWritten*/);
    35513716    AssertRCReturn(rc, rc);
    35523717
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