Changeset 67450 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jun 16, 2017 3:35:31 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67445 r67450 92 92 #define RTFSISOMAKER_CALC_PATHREC_SIZE(a_cbNameInDirRec) \ 93 93 ( RT_UOFFSETOF(ISO9660PATHREC, achDirId[(a_cbNameInDirRec) + ((a_cbNameInDirRec) & 1)]) ) 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) 94 108 95 109 … … 488 502 /** Pointer to the primary volume descriptor. */ 489 503 PISO9660PRIMARYVOLDESC pPrimaryVolDesc; 490 /** El Torito volume descriptor. 491 * @todo fix type */ 492 PISO9660BOOTRECORD pElToritoDesc; 504 /** El Torito volume descriptor. */ 505 PISO9660BOOTRECORDELTORITO pElToritoDesc; 493 506 /** Pointer to the primary volume descriptor. */ 494 507 PISO9660SUPVOLDESC pJolietVolDesc; … … 2935 2948 pFile->Core.cNotOrphan = 1; 2936 2949 2937 /* Save file pointer and we're done. */2950 /* Save file pointer and allocate a volume descriptor. */ 2938 2951 pThis->pBootCatFile = pFile; 2952 pThis->cVolumeDescriptors++; 2953 2939 2954 return VINF_SUCCESS; 2940 2955 } … … 3140 3155 uint8_t idPlatform, const char *pszString) 3141 3156 { 3142 RT_NOREF(hIsoMaker, idxBootCat, cEntries, idPlatform, pszString); 3143 return VERR_NOT_IMPLEMENTED; 3157 /* 3158 * Validate input. 3159 */ 3160 PRTFSISOMAKERINT pThis = hIsoMaker; 3161 RTFSISOMAKER_ASSERT_VALID_HANDLE_RET(pThis); 3162 3163 AssertReturn(idxBootCat >= 2 && idxBootCat < RT_ELEMENTS(pThis->aBootCatEntries) - 1U, VERR_OUT_OF_RANGE); 3164 AssertReturn(cEntries < RT_ELEMENTS(pThis->aBootCatEntries) - 2U - 1U, VERR_OUT_OF_RANGE); 3165 AssertReturn(idxBootCat + cEntries + 1 < RT_ELEMENTS(pThis->aBootCatEntries), VERR_OUT_OF_RANGE); 3166 3167 size_t cchString = 0; 3168 if (pszString) 3169 { 3170 cchString = RTStrCalcLatin1Len(pszString); 3171 AssertReturn(cchString < RT_SIZEOFMEMB(ISO9660ELTORITOVALIDATIONENTRY, achId), VERR_OUT_OF_RANGE); 3172 } 3173 3174 /* 3175 * Make sure we've got a boot file. 3176 */ 3177 int rc = rtFsIsoMakerEnsureBootCatFile(pThis); 3178 if (RT_SUCCESS(rc)) 3179 { 3180 /* 3181 * Construct the entry data. 3182 */ 3183 ISO9660ELTORITOSECTIONHEADER Entry; 3184 Entry.bHeaderId = ISO9660_ELTORITO_HEADER_ID_SECTION_HEADER; 3185 Entry.bPlatformId = idPlatform; 3186 Entry.cEntries = RT_H2LE_U16(cEntries); 3187 RT_ZERO(Entry.achSectionId); 3188 if (cchString) 3189 { 3190 char *pszTmp = Entry.achSectionId; 3191 rc = RTStrToLatin1Ex(pszString, RTSTR_MAX, &pszTmp, sizeof(Entry.achSectionId), NULL); 3192 AssertRC(rc); 3193 } 3194 3195 /* 3196 * Write the entry and update our internal tracker. 3197 */ 3198 rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, 32 * idxBootCat, &Entry, sizeof(Entry), NULL); 3199 if (RT_SUCCESS(rc)) 3200 { 3201 if (pThis->aBootCatEntries[idxBootCat].pBootFile != NULL) 3202 { 3203 pThis->aBootCatEntries[idxBootCat].pBootFile->Core.cNotOrphan--; 3204 pThis->aBootCatEntries[idxBootCat].pBootFile = NULL; 3205 } 3206 3207 pThis->aBootCatEntries[idxBootCat].bType = ISO9660_ELTORITO_HEADER_ID_SECTION_HEADER; 3208 pThis->aBootCatEntries[idxBootCat].cEntries = cEntries + 1; 3209 } 3210 } 3211 return rc; 3144 3212 } 3145 3213 … … 3194 3262 3195 3263 /** 3196 * Finalizes the El Torito boot stuff .3264 * Finalizes the El Torito boot stuff, part 1. 3197 3265 * 3198 3266 * This includes generating the boot catalog data and fixing the location of all … … 3201 3269 * @returns IPRT status code. 3202 3270 * @param pThis The ISO maker instance. 3203 * @param poffData The data offset (in/out). 3204 */ 3205 static int rtFsIsoMakerFinalizeBootStuff(PRTFSISOMAKERINT pThis, uint64_t *poffData) 3206 { 3207 RT_NOREF(pThis, poffData); 3271 */ 3272 static int rtFsIsoMakerFinalizeBootStuffPart1(PRTFSISOMAKERINT pThis) 3273 { 3274 /* 3275 * Anything? 3276 */ 3277 if (!pThis->pBootCatFile) 3278 return VINF_SUCCESS; 3279 3280 /* 3281 * Validate the boot catalog file. 3282 */ 3283 AssertReturn(pThis->aBootCatEntries[0].bType == ISO9660_ELTORITO_HEADER_ID_VALIDATION_ENTRY, 3284 VERR_ISOMK_BOOT_CAT_NO_VALIDATION_ENTRY); 3285 AssertReturn(pThis->aBootCatEntries[1].pBootFile != NULL, VERR_ISOMK_BOOT_CAT_NO_DEFAULT_ENTRY); 3286 3287 /* Check any sections following the default one. */ 3288 uint32_t cEntries = 2; 3289 while ( cEntries < RT_ELEMENTS(pThis->aBootCatEntries) - 1U 3290 && pThis->aBootCatEntries[cEntries].cEntries > 0) 3291 { 3292 AssertReturn(pThis->aBootCatEntries[cEntries].bType == ISO9660_ELTORITO_HEADER_ID_SECTION_HEADER, 3293 VERR_ISOMK_BOOT_CAT_EXPECTED_SECTION_HEADER); 3294 for (uint32_t i = 1; i < pThis->aBootCatEntries[cEntries].cEntries; i++) 3295 AssertReturn(pThis->aBootCatEntries[cEntries].pBootFile != NULL, 3296 pThis->aBootCatEntries[cEntries].cEntries == 0 3297 ? VERR_ISOMK_BOOT_CAT_EMPTY_ENTRY : VERR_ISOMK_BOOT_CAT_INVALID_SECTION_SIZE); 3298 cEntries += pThis->aBootCatEntries[cEntries].cEntries; 3299 } 3300 3301 /* Check that the remaining entries are empty. */ 3302 while (cEntries < RT_ELEMENTS(pThis->aBootCatEntries) - 1U) 3303 { 3304 AssertReturn(pThis->aBootCatEntries[cEntries].cEntries == 0, VERR_ISOMK_BOOT_CAT_ERRATIC_ENTRY); 3305 cEntries++; 3306 } 3307 3308 /* 3309 * Move up the boot images and boot catalog to the start of the image. 3310 */ 3311 for (uint32_t i = RT_ELEMENTS(pThis->aBootCatEntries) - 2; i > 0; i--) 3312 if (pThis->aBootCatEntries[i].pBootFile) 3313 { 3314 RTListNodeRemove(&pThis->aBootCatEntries[i].pBootFile->Core.Entry); 3315 RTListPrepend(&pThis->ObjectHead, &pThis->aBootCatEntries[i].pBootFile->Core.Entry); 3316 } 3317 3318 /* The boot catalog comes first. */ 3319 RTListNodeRemove(&pThis->pBootCatFile->Core.Entry); 3320 RTListPrepend(&pThis->ObjectHead, &pThis->pBootCatFile->Core.Entry); 3321 3322 return VINF_SUCCESS; 3323 } 3324 3325 3326 /** 3327 * Finalizes the El Torito boot stuff, part 1. 3328 * 3329 * This includes generating the boot catalog data and fixing the location of all 3330 * related image files. 3331 * 3332 * @returns IPRT status code. 3333 * @param pThis The ISO maker instance. 3334 */ 3335 static int rtFsIsoMakerFinalizeBootStuffPart2(PRTFSISOMAKERINT pThis) 3336 { 3337 /* 3338 * Fill in the descriptor. 3339 */ 3340 PISO9660BOOTRECORDELTORITO pDesc = pThis->pElToritoDesc; 3341 pDesc->Hdr.bDescType = ISO9660VOLDESC_TYPE_BOOT_RECORD; 3342 pDesc->Hdr.bDescVersion = ISO9660PRIMARYVOLDESC_VERSION; 3343 memcpy(pDesc->Hdr.achStdId, ISO9660VOLDESC_STD_ID, sizeof(pDesc->Hdr.achStdId)); 3344 memcpy(pDesc->achBootSystemId, RT_STR_TUPLE(ISO9660BOOTRECORDELTORITO_BOOT_SYSTEM_ID)); 3345 pDesc->offBootCatalog = RT_H2LE_U32((uint32_t)(pThis->pBootCatFile->offData / RTFSISOMAKER_SECTOR_SIZE)); 3346 3347 /* 3348 * Update the image file locations. 3349 */ 3350 uint32_t cEntries = 2; 3351 for (uint32_t i = 1; i < RT_ELEMENTS(pThis->aBootCatEntries) - 1; i++) 3352 if (pThis->aBootCatEntries[i].pBootFile) 3353 { 3354 uint32_t off = pThis->aBootCatEntries[i].pBootFile->offData / RTFSISOMAKER_SECTOR_SIZE; 3355 off = RT_H2LE_U32(off); 3356 int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, 3357 i * 32 + RT_UOFFSETOF(ISO9660ELTORITOSECTIONENTRY, offBootImage), 3358 &off, sizeof(off), NULL /*pcbWritten*/); 3359 AssertRCReturn(rc, rc); 3360 if (i == cEntries) 3361 cEntries = i + 1; 3362 } 3363 3364 /* 3365 * Write end section. 3366 */ 3367 ISO9660ELTORITOSECTIONHEADER Entry; 3368 Entry.bHeaderId = ISO9660_ELTORITO_HEADER_ID_FINAL_SECTION_HEADER; 3369 Entry.bPlatformId = ISO9660_ELTORITO_PLATFORM_ID_X86; 3370 Entry.cEntries = 0; 3371 RT_ZERO(Entry.achSectionId); 3372 int rc = RTVfsFileWriteAt(pThis->pBootCatFile->u.hVfsFile, cEntries * 32, &Entry, sizeof(Entry), NULL /*pcbWritten*/); 3373 AssertRCReturn(rc, rc); 3374 3208 3375 return VINF_SUCCESS; 3209 3376 } … … 3679 3846 * Allocate and prepare the volume descriptors. 3680 3847 * 3681 * What's not done here gets done later by rtFsIsoMakerFinalizeBootStuff, or at 3682 * teh very end of the finalization by rtFsIsoMakerFinalizeVolumeDescriptors. 3848 * What's not done here gets done later by rtFsIsoMakerFinalizeBootStuffPart2, 3849 * or at teh very end of the finalization by 3850 * rtFsIsoMakerFinalizeVolumeDescriptors. 3683 3851 * 3684 3852 * @returns IPRT status code … … 3699 3867 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3700 3868 3701 if ( true)3869 if (!pThis->pBootCatFile) 3702 3870 pThis->pElToritoDesc = NULL; 3703 3871 else 3704 3872 { 3705 pThis->pElToritoDesc = (PISO9660BOOTRECORD )&pThis->pbVolDescs[offVolDescs];3873 pThis->pElToritoDesc = (PISO9660BOOTRECORDELTORITO)&pThis->pbVolDescs[offVolDescs]; 3706 3874 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3707 3875 } … … 3948 4116 */ 3949 4117 uint64_t offData = _32K + pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE; 3950 rc = rtFsIsoMakerFinalizeBootStuff (pThis, &offData);4118 rc = rtFsIsoMakerFinalizeBootStuffPart1(pThis); 3951 4119 if (RT_SUCCESS(rc)) 3952 4120 { … … 3966 4134 3967 4135 /* 3968 * Finally, finalize the volume descriptors as they depend on some of the 3969 * block allocations done in the previous steps. 4136 * Do a 2nd pass over the boot stuff to finalize locations. 3970 4137 */ 3971 rc = rtFsIsoMakerFinalize VolumeDescriptors(pThis);4138 rc = rtFsIsoMakerFinalizeBootStuffPart2(pThis); 3972 4139 if (RT_SUCCESS(rc)) 3973 4140 { 3974 pThis->fFinalized = true; 3975 return VINF_SUCCESS; 4141 /* 4142 * Finally, finalize the volume descriptors as they depend on some of the 4143 * block allocations done in the previous steps. 4144 */ 4145 rc = rtFsIsoMakerFinalizeVolumeDescriptors(pThis); 4146 if (RT_SUCCESS(rc)) 4147 { 4148 pThis->fFinalized = true; 4149 return VINF_SUCCESS; 4150 } 3976 4151 } 3977 4152 }
Note:
See TracChangeset
for help on using the changeset viewer.