Changeset 67538 in vbox for trunk/src/VBox/Runtime/common/fs/isomaker.cpp
- Timestamp:
- Jun 21, 2017 12:48:19 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67515 r67538 93 93 ( RT_UOFFSETOF(ISO9660PATHREC, achDirId[(a_cbNameInDirRec) + ((a_cbNameInDirRec) & 1)]) ) 94 94 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)108 95 109 96 … … 2360 2347 { 2361 2348 /* 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 /* 2362 2359 * Remove the object from all name spaces. 2363 2360 */ … … 3151 3148 3152 3149 /** 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 */ 3161 RTDECL(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 /** 3153 3234 * Set the validation entry of the boot catalog (this is the first entry). 3154 3235 * … … 3240 3321 * mode segment number). 3241 3322 * @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. 3242 3327 */ 3243 3328 RTDECL(int) RTFsIsoMakerBootCatSetSectionEntry(RTFSISOMAKER hIsoMaker, uint32_t idxBootCat, uint32_t idxImageObj, 3244 3329 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) 3246 3332 { 3247 3333 /* … … 3259 3345 AssertReturn(idxBootCat != 0 && idxBootCat != 2 && idxBootCat < RT_ELEMENTS(pThis->aBootCatEntries) - 1U, VERR_OUT_OF_RANGE); 3260 3346 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 3261 3369 /* 3262 3370 * Make sure we've got a boot file. … … 3268 3376 * Construct the entry. 3269 3377 */ 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))); 3281 3397 3282 3398 /* 3283 3399 * Write it and update our internal tracker. 3284 3400 */ 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); 3286 3403 if (RT_SUCCESS(rc)) 3287 3404 { … … 3294 3411 } 3295 3412 3296 pThis->aBootCatEntries[idxBootCat].bType = Entry.bBootIndicator;3413 pThis->aBootCatEntries[idxBootCat].bType = u.Entry.bBootIndicator; 3297 3414 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 } 3298 3461 } 3299 3462 } … … 3357 3520 * Write the entry and update our internal tracker. 3358 3521 */ 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); 3360 3524 if (RT_SUCCESS(rc)) 3361 3525 { … … 3475 3639 * Fixate the size of the boot catalog file. 3476 3640 */ 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); 3479 3643 3480 3644 /* … … 3533 3697 off = RT_H2LE_U32(off); 3534 3698 int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, 3535 i * 32+ RT_UOFFSETOF(ISO9660ELTORITOSECTIONENTRY, offBootImage),3699 i * ISO9660_ELTORITO_ENTRY_SIZE + RT_UOFFSETOF(ISO9660ELTORITOSECTIONENTRY, offBootImage), 3536 3700 &off, sizeof(off), NULL /*pcbWritten*/); 3537 3701 AssertRCReturn(rc, rc); … … 3548 3712 Entry.cEntries = 0; 3549 3713 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*/); 3551 3716 AssertRCReturn(rc, rc); 3552 3717
Note:
See TracChangeset
for help on using the changeset viewer.