- Timestamp:
- Jun 9, 2017 9:34:32 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67325 r67327 35 35 #include <iprt/asm.h> 36 36 #include <iprt/assert.h> 37 #include <iprt/buildconfig.h> 37 38 #include <iprt/err.h> 38 39 #include <iprt/ctype.h> … … 243 244 * When not NULL, this may be pointing to heap or g_szTransTbl. */ 244 245 char *pszTransTbl; 246 /** The system ID (ISO9660PRIMARYVOLDESC::achSystemId). 247 * Empty if NULL. */ 248 char *pszSystemId; 249 /** The volume ID / label (ISO9660PRIMARYVOLDESC::achVolumeId). 250 * A string representation of RTFSISOMAKERINT::ImageCreationTime if NULL. */ 251 char *pszVolumeId; 252 /** The volume set ID (ISO9660PRIMARYVOLDESC::achVolumeSetId). Empty if NULL. */ 253 char *pszVolumeSetId; 254 /** The publisher ID or (root) file reference (ISO9660PRIMARYVOLDESC::achPublisherId). Empty if NULL. */ 255 char *pszPublisherId; 256 /** The data preperer ID or (root) file reference (ISO9660PRIMARYVOLDESC::achDataPreparerId). 257 * Defaults to g_szPreparerIdPrimaryIso or g_szPreparerIdJoliet. */ 258 char *pszDataPreparerId; 259 /** The application ID or (root) file reference (ISO9660PRIMARYVOLDESC::achApplicationId). None if NULL. */ 260 char *pszApplicationId; 261 /** The copyright (root) file identifier (ISO9660PRIMARYVOLDESC::achCopyrightFileId). None if NULL. */ 262 char *pszCopyrightFileId; 263 /** The abstract (root) file identifier (ISO9660PRIMARYVOLDESC::achAbstractFileId). None if NULL. */ 264 char *pszAbstractFileId; 265 /** The bibliographic (root) file identifier (ISO9660PRIMARYVOLDESC::achBibliographicFileId). None if NULL. */ 266 char *pszBibliographicFileId; 245 267 } RTFSISOMAKERNAMESPACE; 246 268 /** Pointer to a namespace. */ … … 408 430 RTFMODE fDefaultDirMode; 409 431 410 411 432 /** @name Finalized image stuff 412 433 * @{ */ … … 444 465 * This always follows offPathTableL. */ 445 466 uint64_t offPathTableM; 467 /** The size of the path table. */ 468 uint32_t cbPathTable; 446 469 /** List of finalized directories for this namespace. 447 470 * The list is in path table order so it can be generated on the fly. The … … 537 560 538 561 /** The default translation table filename. */ 539 static char g_szTransTbl[] = "TRANS.TBL"; 562 static const char g_szTransTbl[] = "TRANS.TBL"; 563 /** The default data preparer ID for the primary ISO-9660 volume descriptor. */ 564 static char g_szPreparerIdPrimaryIso[64] = ""; 565 /** The default data preparer ID for the joliet volume descriptor. */ 566 static char g_szPreparerIdJoliet[64] = ""; 540 567 541 568 … … 573 600 VERR_INTERNAL_ERROR_5); 574 601 602 if (g_szPreparerIdPrimaryIso[0] == '\0') 603 RTStrPrintf(g_szPreparerIdPrimaryIso, sizeof(g_szPreparerIdPrimaryIso), "IPRT ISO MAKER V%u.%u.%u R%s", 604 RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild(), RTBldCfgRevision()); 605 if (g_szPreparerIdJoliet[0] == '\0') 606 RTStrPrintf(g_szPreparerIdJoliet, sizeof(g_szPreparerIdJoliet), 607 "IPRT ISO Maker v%s r%s", RTBldCfgVersion(), RTBldCfgRevision()); 608 575 609 /* 576 610 * Create the instance with defaults. … … 588 622 pThis->PrimaryIso.uLevel = 3; /* 30 char names, large files */ 589 623 pThis->PrimaryIso.uRockRidgeLevel = 1; 590 pThis->PrimaryIso.pszTransTbl = g_szTransTbl; 624 pThis->PrimaryIso.pszTransTbl = (char *)g_szTransTbl; 625 //pThis->PrimaryIso.pszSystemId = NULL; 626 //pThis->PrimaryIso.pszVolumeId = NULL; 627 //pThis->PrimaryIso.pszSetVolumeId = NULL; 628 //pThis->PrimaryIso.pszPublisherId = NULL; 629 pThis->PrimaryIso.pszDataPreparerId = g_szPreparerIdPrimaryIso; 630 //pThis->PrimaryIso.pszApplicationId = NULL; 631 //pThis->PrimaryIso.pszCopyrightFileId= NULL; 632 //pThis->PrimaryIso.pszAbstractFileId = NULL; 633 //pThis->PrimaryIso.pszBibliographicFileId = NULL; 634 591 635 pThis->Joliet.fNamespace = RTFSISOMAKER_NAMESPACE_JOLIET; 592 636 pThis->Joliet.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName); … … 594 638 //pThis->Joliet.uRockRidgeLevel = 0; 595 639 //pThis->Joliet.pszTransTbl = NULL; 640 //pThis->Joliet.pszSystemId = NULL; 641 //pThis->Joliet.pszVolumeId = NULL; 642 //pThis->Joliet.pszSetVolumeId = NULL; 643 //pThis->Joliet.pszPublisherId = NULL; 644 pThis->Joliet.pszDataPreparerId = g_szPreparerIdJoliet; 645 //pThis->Joliet.pszApplicationId = NULL; 646 //pThis->Joliet.pszCopyrightFileId = NULL; 647 //pThis->Joliet.pszAbstractFileId = NULL; 648 //pThis->Joliet.pszBibliographicFileId = NULL; 649 596 650 pThis->Udf.fNamespace = RTFSISOMAKER_NAMESPACE_UDF; 597 651 pThis->Udf.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName); … … 599 653 //pThis->Udf.uRockRidgeLevel = 0; 600 654 //pThis->Udf.pszTransTbl = NULL; 655 //pThis->Udf.uRockRidgeLevel = 0; 656 //pThis->Udf.pszTransTbl = NULL; 657 //pThis->Udf.pszSystemId = NULL; 658 //pThis->Udf.pszVolumeId = NULL; 659 //pThis->Udf.pszSetVolumeId = NULL; 660 //pThis->Udf.pszPublisherId = NULL; 661 //pThis->Udf.pszDataPreparerId = NULL; 662 //pThis->Udf.pszApplicationId = NULL; 663 //pThis->Udf.pszCopyrightFileId = NULL; 664 //pThis->Udf.pszAbstractFileId = NULL; 665 //pThis->Udf.pszBibliographicFileId = NULL; 666 601 667 pThis->Hfs.fNamespace = RTFSISOMAKER_NAMESPACE_HFS; 602 668 pThis->Hfs.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName); … … 604 670 //pThis->Hfs.uRockRidgeLevel = 0; 605 671 //pThis->Hfs.pszTransTbl = NULL; 672 //pThis->Hfs.pszSystemId = NULL; 673 //pThis->Hfs.pszVolumeId = NULL; 674 //pThis->Hfs.pszSetVolumeId = NULL; 675 //pThis->Hfs.pszPublisherId = NULL; 676 //pThis->Hfs.pszDataPreparerId = NULL; 677 //pThis->Hfs.pszApplicationId = NULL; 678 //pThis->Hfs.pszCopyrightFileId = NULL; 679 //pThis->Hfs.pszAbstractFileId = NULL; 680 //pThis->Hfs.pszBibliographicFileId = NULL; 606 681 607 682 RTListInit(&pThis->ObjectHead); … … 627 702 pThis->PrimaryIsoDirs.offPathTableL = UINT64_MAX; 628 703 pThis->PrimaryIsoDirs.offPathTableM = UINT64_MAX; 704 pThis->PrimaryIsoDirs.cbPathTable = 0; 629 705 RTListInit(&pThis->PrimaryIsoDirs.FinalizedDirs); 630 706 //pThis->PrimaryIsoDirs.pRRSpillFile = NULL; … … 633 709 pThis->JolietDirs.offPathTableL = UINT64_MAX; 634 710 pThis->JolietDirs.offPathTableM = UINT64_MAX; 711 pThis->JolietDirs.cbPathTable = 0; 635 712 RTListInit(&pThis->JolietDirs.FinalizedDirs); 636 713 //pThis->JolietDirs.pRRSpillFile = NULL; … … 761 838 RTMemFree(pNamespace->pszTransTbl); 762 839 pNamespace->pszTransTbl = NULL; 840 } 841 842 /* 843 * Free string IDs. 844 */ 845 if (pNamespace->pszSystemId) 846 { 847 RTMemFree(pNamespace->pszSystemId); 848 pNamespace->pszSystemId = NULL; 849 } 850 851 if (pNamespace->pszVolumeId) 852 { 853 RTMemFree(pNamespace->pszVolumeId); 854 pNamespace->pszVolumeId = NULL; 855 } 856 857 if (pNamespace->pszVolumeSetId) 858 { 859 RTMemFree(pNamespace->pszVolumeSetId); 860 pNamespace->pszVolumeSetId = NULL; 861 } 862 863 if (pNamespace->pszPublisherId) 864 { 865 RTMemFree(pNamespace->pszPublisherId); 866 pNamespace->pszPublisherId = NULL; 867 } 868 869 if (pNamespace->pszDataPreparerId) 870 { 871 if ( pNamespace->pszDataPreparerId != g_szPreparerIdPrimaryIso 872 && pNamespace->pszDataPreparerId != g_szPreparerIdJoliet) 873 RTMemFree(pNamespace->pszDataPreparerId); 874 pNamespace->pszDataPreparerId = NULL; 875 } 876 877 if (pNamespace->pszApplicationId) 878 { 879 RTMemFree(pNamespace->pszApplicationId); 880 pNamespace->pszApplicationId = NULL; 881 } 882 883 if (pNamespace->pszCopyrightFileId) 884 { 885 RTMemFree(pNamespace->pszCopyrightFileId); 886 pNamespace->pszCopyrightFileId = NULL; 887 } 888 889 if (pNamespace->pszAbstractFileId) 890 { 891 RTMemFree(pNamespace->pszAbstractFileId); 892 pNamespace->pszAbstractFileId = NULL; 893 } 894 895 if (pNamespace->pszBibliographicFileId) 896 { 897 RTMemFree(pNamespace->pszBibliographicFileId); 898 pNamespace->pszBibliographicFileId = NULL; 763 899 } 764 900 } … … 2755 2891 * Calculate the path table offsets and move past them. 2756 2892 */ 2893 pFinalizedDirs->cbPathTable = cbPathTable; 2757 2894 pFinalizedDirs->offPathTableL = *poffData; 2758 2895 *poffData += RT_ALIGN_64(cbPathTable, RTFSISOMAKER_SECTOR_SIZE); … … 2836 2973 2837 2974 /** 2838 * Finalizes the volume descriptors. 2839 * 2840 * This will set the RTFSISOMAKERFILE::offData members. 2841 * 2842 * @returns IPRT status code. 2975 * Copies the given string as UTF-16 and pad unused space in the destination 2976 * with spaces. 2977 * 2978 * @param pachDst The destination field. C type is char, but real life 2979 * type is UTF-16 / UCS-2. 2980 * @param cchDst The size of the destination field. 2981 * @param pszSrc The source string. NULL is treated like empty string. 2982 */ 2983 static void rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(char *pachDst, size_t cchDst, const char *pszSrc) 2984 { 2985 size_t const cwcDst = cchDst / sizeof(RTUTF16); 2986 size_t cwcSrc = 0; 2987 if (pszSrc) 2988 { 2989 RTUTF16 wszSrc[256]; 2990 PRTUTF16 pwszSrc = wszSrc; 2991 int rc = RTStrToUtf16Ex(pszSrc, RTSTR_MAX, &pwszSrc, RT_ELEMENTS(wszSrc), &cwcSrc); 2992 AssertRCStmt(rc, cwcSrc = 0); 2993 2994 if (cwcSrc > cchDst / sizeof(RTUTF16)) 2995 cwcSrc = cchDst / sizeof(RTUTF16); 2996 memcpy(pachDst, wszSrc, cwcSrc * sizeof(RTUTF16)); 2997 } 2998 if (cwcSrc < cwcDst) 2999 { 3000 PRTUTF16 pwcDst = (PRTUTF16)pachDst; 3001 pwcDst += cwcSrc; 3002 while (cwcSrc < cwcDst) 3003 { 3004 *pwcDst++ = ' '; 3005 cwcSrc++; 3006 } 3007 } 3008 } 3009 3010 3011 /** 3012 * Copies the given string and pad unused space in the destination with spaces. 3013 * 3014 * @param pachDst The destination field. 3015 * @param cchDst The size of the destination field. 3016 * @param pszSrc The source string. NULL is treated like empty string. 3017 */ 3018 static void rtFsIsoMakerFinalizeCopyAndSpacePad(char *pachDst, size_t cchDst, const char *pszSrc) 3019 { 3020 size_t cchSrc; 3021 if (!pszSrc) 3022 cchSrc = 0; 3023 else 3024 { 3025 cchSrc = strlen(pszSrc); 3026 if (cchSrc > cchDst) 3027 cchSrc = cchDst; 3028 memcpy(pachDst, pszSrc, cchSrc); 3029 } 3030 if (cchSrc < cchDst) 3031 memset(&pachDst[cchSrc], ' ', cchDst - cchSrc); 3032 } 3033 3034 3035 /** 3036 * Formats a timespec as an ISO-9660 ascii timestamp. 3037 * 3038 * @param pTime The timespec to format. 3039 * @param pIsoTs The ISO-9660 timestamp destination buffer. 3040 */ 3041 static void rtFsIsoMakerTimespecToIso9660Timestamp(PCRTTIMESPEC pTime, PISO9660TIMESTAMP pIsoTs) 3042 { 3043 RTTIME Exploded; 3044 RTTimeExplode(&Exploded, pTime); 3045 3046 char szTmp[64]; 3047 #define FORMAT_FIELD(a_achDst, a_uSrc) \ 3048 do { \ 3049 RTStrFormatU32(szTmp, sizeof(szTmp), a_uSrc, 10, sizeof(a_achDst), sizeof(a_achDst), \ 3050 RTSTR_F_ZEROPAD | RTSTR_F_WIDTH | RTSTR_F_PRECISION); \ 3051 memcpy(a_achDst, szTmp, sizeof(a_achDst)); \ 3052 } while (0) 3053 FORMAT_FIELD(pIsoTs->achYear, Exploded.i32Year); 3054 FORMAT_FIELD(pIsoTs->achMonth, Exploded.u8Month); 3055 FORMAT_FIELD(pIsoTs->achDay, Exploded.u8MonthDay); 3056 FORMAT_FIELD(pIsoTs->achHour, Exploded.u8Hour); 3057 FORMAT_FIELD(pIsoTs->achMinute, Exploded.u8Minute); 3058 FORMAT_FIELD(pIsoTs->achSecond, Exploded.u8Second); 3059 FORMAT_FIELD(pIsoTs->achCentisecond, Exploded.u32Nanosecond / RT_NS_10MS); 3060 #undef FORMAT_FIELD 3061 pIsoTs->offUtc = 0; 3062 } 3063 3064 3065 /** 3066 * Formats a timespec as an ISO-9660 record timestamp. 3067 * 3068 * @param pTime The timespec to format. 3069 * @param pIsoTs The ISO-9660 timestamp destination buffer. 3070 */ 3071 static void rtFsIsoMakerTimespecToIso9660RecTimestamp(PCRTTIMESPEC pTime, PISO9660RECTIMESTAMP pIsoRecTs) 3072 { 3073 RTTIME Exploded; 3074 RTTimeExplode(&Exploded, pTime); 3075 3076 pIsoRecTs->bYear = Exploded.i32Year >= 1900 ? Exploded.i32Year - 1900 : 0; 3077 pIsoRecTs->bMonth = Exploded.u8Month; 3078 pIsoRecTs->bDay = Exploded.u8MonthDay; 3079 pIsoRecTs->bHour = Exploded.u8Hour; 3080 pIsoRecTs->bMinute = Exploded.u8Minute; 3081 pIsoRecTs->bSecond = Exploded.u8Second; 3082 pIsoRecTs->offUtc = 0; 3083 } 3084 3085 3086 /** 3087 * Allocate and prepare the volume descriptors. 3088 * 3089 * What's not done here gets done later by rtFsIsoMakerFinalizeBootStuff, or at 3090 * teh very end of the finalization by rtFsIsoMakerFinalizeVolumeDescriptors. 3091 * 3092 * @returns IPRT status code 2843 3093 * @param pThis The ISO maker instance. 2844 3094 */ 2845 static int rtFsIsoMakerFinalizeVolumeDescriptors(PRTFSISOMAKERINT pThis) 2846 { 2847 AssertReturn(pThis->pbVolDescs && pThis->pPrimaryVolDesc && pThis->pTerminatorVolDesc, VERR_INTERNAL_ERROR_3); 2848 2849 /* 2850 * The primary descriptor. 2851 */ 2852 2853 2854 /* 2855 * The terminator record. 3095 static int rtFsIsoMakerFinalizePrepVolumeDescriptors(PRTFSISOMAKERINT pThis) 3096 { 3097 /* 3098 * Allocate and calc pointers. 3099 */ 3100 RTMemFree(pThis->pbVolDescs); 3101 pThis->pbVolDescs = (uint8_t *)RTMemAllocZ(pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE); 3102 AssertReturn(pThis->pbVolDescs, VERR_NO_MEMORY); 3103 3104 uint32_t offVolDescs = 0; 3105 3106 pThis->pPrimaryVolDesc = (PISO9660PRIMARYVOLDESC)&pThis->pbVolDescs[offVolDescs]; 3107 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3108 3109 if (true) 3110 pThis->pElToritoDesc = NULL; 3111 else 3112 { 3113 pThis->pElToritoDesc = (PISO9660BOOTRECORD)&pThis->pbVolDescs[offVolDescs]; 3114 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3115 } 3116 3117 if (!pThis->Joliet.uLevel) 3118 pThis->pJolietVolDesc = NULL; 3119 else 3120 { 3121 pThis->pJolietVolDesc = (PISO9660SUPVOLDESC)&pThis->pbVolDescs[offVolDescs]; 3122 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3123 } 3124 3125 pThis->pTerminatorVolDesc = (PISO9660VOLDESCHDR)&pThis->pbVolDescs[offVolDescs]; 3126 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 3127 3128 if (pThis->Udf.uLevel > 0) 3129 { 3130 /** @todo UDF descriptors. */ 3131 } 3132 AssertReturn(offVolDescs == pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE, VERR_INTERNAL_ERROR_2); 3133 3134 /* 3135 * This may be needed later. 3136 */ 3137 char szImageCreationTime[42]; 3138 RTTimeSpecToString(&pThis->ImageCreationTime, szImageCreationTime, sizeof(szImageCreationTime)); 3139 3140 /* 3141 * Initialize the primary descriptor. 3142 */ 3143 PISO9660PRIMARYVOLDESC pPrimary = pThis->pPrimaryVolDesc; 3144 3145 pPrimary->Hdr.bDescType = ISO9660VOLDESC_TYPE_PRIMARY; 3146 pPrimary->Hdr.bDescVersion = ISO9660PRIMARYVOLDESC_VERSION; 3147 memcpy(pPrimary->Hdr.achStdId, ISO9660VOLDESC_STD_ID, sizeof(pPrimary->Hdr.achStdId)); 3148 //pPrimary->bPadding8 = 0; 3149 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achSystemId, sizeof(pPrimary->achSystemId), pThis->PrimaryIso.pszSystemId); 3150 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achVolumeId, sizeof(pPrimary->achVolumeId), 3151 pThis->PrimaryIso.pszVolumeId ? pThis->PrimaryIso.pszVolumeId : szImageCreationTime); 3152 //pPrimary->Unused73 = {0} 3153 //pPrimary->VolumeSpaceSize = later 3154 //pPrimary->abUnused89 = {0} 3155 pPrimary->cVolumesInSet.be = RT_H2BE_U16_C(1); 3156 pPrimary->cVolumesInSet.le = RT_H2LE_U16_C(1); 3157 pPrimary->VolumeSeqNo.be = RT_H2BE_U16_C(1); 3158 pPrimary->VolumeSeqNo.le = RT_H2LE_U16_C(1); 3159 pPrimary->cbLogicalBlock.be = RT_H2BE_U16_C(RTFSISOMAKER_SECTOR_SIZE); 3160 pPrimary->cbLogicalBlock.le = RT_H2LE_U16_C(RTFSISOMAKER_SECTOR_SIZE); 3161 //pPrimary->cbPathTable = later 3162 //pPrimary->offTypeLPathTable = later 3163 //pPrimary->offOptionalTypeLPathTable = {0} 3164 //pPrimary->offTypeMPathTable = later 3165 //pPrimary->offOptionalTypeMPathTable = {0} 3166 //pPrimary->RootDir = later 3167 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achVolumeSetId, sizeof(pPrimary->achVolumeSetId), 3168 pThis->PrimaryIso.pszVolumeSetId); 3169 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achPublisherId, sizeof(pPrimary->achPublisherId), 3170 pThis->PrimaryIso.pszPublisherId); 3171 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achDataPreparerId, sizeof(pPrimary->achDataPreparerId), 3172 pThis->PrimaryIso.pszDataPreparerId); 3173 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achApplicationId, sizeof(pPrimary->achApplicationId), 3174 pThis->PrimaryIso.pszApplicationId); 3175 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achCopyrightFileId, sizeof(pPrimary->achCopyrightFileId), 3176 pThis->PrimaryIso.pszCopyrightFileId); 3177 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achAbstractFileId, sizeof(pPrimary->achAbstractFileId), 3178 pThis->PrimaryIso.pszAbstractFileId); 3179 rtFsIsoMakerFinalizeCopyAndSpacePad(pPrimary->achBibliographicFileId, sizeof(pPrimary->achBibliographicFileId), 3180 pThis->PrimaryIso.pszBibliographicFileId); 3181 rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pPrimary->BirthTime); 3182 rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pPrimary->ModifyTime); 3183 //RT_ZERO(pPrimary->ExpireTime); 3184 //RT_ZERO(pPrimary->EffectiveTime) 3185 pPrimary->bFileStructureVersion = ISO9660_FILE_STRUCTURE_VERSION; 3186 //pPrimary->bReserved883 = 0; 3187 //RT_ZERO(pPrimary->abAppUse); 3188 //RT_ZERO(pPrimary->abReserved1396); 3189 3190 /* 3191 * Initialize the joliet descriptor if included. 3192 */ 3193 PISO9660SUPVOLDESC pJoliet = pThis->pJolietVolDesc; 3194 if (pJoliet) 3195 { 3196 pJoliet->Hdr.bDescType = ISO9660VOLDESC_TYPE_SUPPLEMENTARY; 3197 pJoliet->Hdr.bDescVersion = ISO9660SUPVOLDESC_VERSION; 3198 memcpy(pJoliet->Hdr.achStdId, ISO9660VOLDESC_STD_ID, sizeof(pJoliet->Hdr.achStdId)); 3199 pJoliet->fVolumeFlags = ISO9660SUPVOLDESC_VOL_F_ESC_ONLY_REG; 3200 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achSystemId, sizeof(pJoliet->achSystemId), pThis->Joliet.pszSystemId); 3201 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achVolumeId, sizeof(pJoliet->achVolumeId), 3202 pThis->Joliet.pszVolumeId ? pThis->Joliet.pszVolumeId : szImageCreationTime); 3203 //pJoliet->Unused73 = {0} 3204 //pJoliet->VolumeSpaceSize = later 3205 pJoliet->abEscapeSequences[0] = ISO9660_JOLIET_ESC_SEQ_0; 3206 pJoliet->abEscapeSequences[1] = ISO9660_JOLIET_ESC_SEQ_1; 3207 pJoliet->abEscapeSequences[1] = pThis->Joliet.uLevel == 1 ? ISO9660_JOLIET_ESC_SEQ_2_LEVEL_1 3208 : pThis->Joliet.uLevel == 2 ? ISO9660_JOLIET_ESC_SEQ_2_LEVEL_2 3209 : ISO9660_JOLIET_ESC_SEQ_2_LEVEL_3; 3210 pJoliet->cVolumesInSet.be = RT_H2BE_U16_C(1); 3211 pJoliet->cVolumesInSet.le = RT_H2LE_U16_C(1); 3212 pJoliet->VolumeSeqNo.be = RT_H2BE_U16_C(1); 3213 pJoliet->VolumeSeqNo.le = RT_H2LE_U16_C(1); 3214 pJoliet->cbLogicalBlock.be = RT_H2BE_U16_C(RTFSISOMAKER_SECTOR_SIZE); 3215 pJoliet->cbLogicalBlock.le = RT_H2LE_U16_C(RTFSISOMAKER_SECTOR_SIZE); 3216 //pJoliet->cbPathTable = later 3217 //pJoliet->offTypeLPathTable = later 3218 //pJoliet->offOptionalTypeLPathTable = {0} 3219 //pJoliet->offTypeMPathTable = later 3220 //pJoliet->offOptionalTypeMPathTable = {0} 3221 //pJoliet->RootDir = later 3222 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achVolumeSetId, sizeof(pJoliet->achVolumeSetId), 3223 pThis->Joliet.pszVolumeSetId); 3224 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achPublisherId, sizeof(pJoliet->achPublisherId), 3225 pThis->Joliet.pszPublisherId); 3226 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achDataPreparerId, sizeof(pJoliet->achDataPreparerId), 3227 pThis->Joliet.pszDataPreparerId); 3228 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achApplicationId, sizeof(pJoliet->achApplicationId), 3229 pThis->Joliet.pszApplicationId); 3230 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achCopyrightFileId, sizeof(pJoliet->achCopyrightFileId), 3231 pThis->Joliet.pszCopyrightFileId); 3232 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achAbstractFileId, sizeof(pJoliet->achAbstractFileId), 3233 pThis->Joliet.pszAbstractFileId); 3234 rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achBibliographicFileId, sizeof(pJoliet->achBibliographicFileId), 3235 pThis->Joliet.pszBibliographicFileId); 3236 rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pJoliet->BirthTime); 3237 rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pJoliet->ModifyTime); 3238 //RT_ZERO(pJoliet->ExpireTime); 3239 //RT_ZERO(pJoliet->EffectiveTime) 3240 pJoliet->bFileStructureVersion = ISO9660_FILE_STRUCTURE_VERSION; 3241 //pJoliet->bReserved883 = 0; 3242 //RT_ZERO(pJoliet->abAppUse); 3243 //RT_ZERO(pJoliet->abReserved1396); 3244 } 3245 3246 /* 3247 * The ISO-9660 terminator descriptor. 2856 3248 */ 2857 3249 pThis->pTerminatorVolDesc->bDescType = ISO9660VOLDESC_TYPE_TERMINATOR; … … 2864 3256 2865 3257 /** 3258 * Finalizes the volume descriptors. 3259 * 3260 * This will set the RTFSISOMAKERFILE::offData members. 3261 * 3262 * @returns IPRT status code. 3263 * @param pThis The ISO maker instance. 3264 */ 3265 static int rtFsIsoMakerFinalizeVolumeDescriptors(PRTFSISOMAKERINT pThis) 3266 { 3267 AssertReturn(pThis->pbVolDescs && pThis->pPrimaryVolDesc && pThis->pTerminatorVolDesc, VERR_INTERNAL_ERROR_3); 3268 3269 /* 3270 * Primary descriptor. 3271 */ 3272 PISO9660PRIMARYVOLDESC pPrimary = pThis->pPrimaryVolDesc; 3273 3274 pPrimary->VolumeSpaceSize.be = RT_H2BE_U32(pThis->cbFinalizedImage / RTFSISOMAKER_SECTOR_SIZE); 3275 pPrimary->VolumeSpaceSize.le = RT_H2LE_U32(pThis->cbFinalizedImage / RTFSISOMAKER_SECTOR_SIZE); 3276 pPrimary->cbPathTable.be = RT_H2BE_U32(pThis->JolietDirs.cbPathTable); 3277 pPrimary->cbPathTable.le = RT_H2LE_U32(pThis->JolietDirs.cbPathTable); 3278 pPrimary->offTypeLPathTable = RT_H2LE_U32(pThis->JolietDirs.offPathTableL); 3279 pPrimary->offTypeMPathTable = RT_H2BE_U32(pThis->JolietDirs.offPathTableM); 3280 pPrimary->RootDir.DirRec.cbDirRec = sizeof(pPrimary->RootDir); 3281 pPrimary->RootDir.DirRec.cExtAttrBlocks = 0; 3282 pPrimary->RootDir.DirRec.offExtent.be = RT_H2BE_U32(pThis->PrimaryIso.pRoot->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3283 pPrimary->RootDir.DirRec.offExtent.le = RT_H2LE_U32(pThis->PrimaryIso.pRoot->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3284 pPrimary->RootDir.DirRec.cbData.be = RT_H2BE_U32(pThis->PrimaryIso.pRoot->pDir->cbDir); 3285 pPrimary->RootDir.DirRec.cbData.le = RT_H2LE_U32(pThis->PrimaryIso.pRoot->pDir->cbDir); 3286 rtFsIsoMakerTimespecToIso9660RecTimestamp(&pThis->PrimaryIso.pRoot->pObj->BirthTime, &pPrimary->RootDir.DirRec.RecTime); 3287 pPrimary->RootDir.DirRec.fFileFlags = ISO9660_FILE_FLAGS_DIRECTORY; 3288 pPrimary->RootDir.DirRec.bFileUnitSize = 0; 3289 pPrimary->RootDir.DirRec.bInterleaveGapSize = 0; 3290 pPrimary->RootDir.DirRec.VolumeSeqNo.be = RT_H2BE_U16_C(1); 3291 pPrimary->RootDir.DirRec.VolumeSeqNo.le = RT_H2BE_U16_C(1); 3292 pPrimary->RootDir.DirRec.bFileIdLength = 1; 3293 pPrimary->RootDir.DirRec.achFileId[1] = 0x00; 3294 3295 /* 3296 * Initialize the joliet descriptor if included. 3297 */ 3298 PISO9660SUPVOLDESC pJoliet = pThis->pJolietVolDesc; 3299 if (pJoliet) 3300 { 3301 pJoliet->VolumeSpaceSize = pPrimary->VolumeSpaceSize; 3302 pJoliet->cbPathTable.be = RT_H2BE_U32(pThis->JolietDirs.cbPathTable); 3303 pJoliet->cbPathTable.le = RT_H2LE_U32(pThis->JolietDirs.cbPathTable); 3304 pJoliet->offTypeLPathTable = RT_H2LE_U32(pThis->JolietDirs.offPathTableL); 3305 pJoliet->offTypeMPathTable = RT_H2BE_U32(pThis->JolietDirs.offPathTableM); 3306 pJoliet->RootDir.DirRec.cbDirRec = sizeof(pJoliet->RootDir); 3307 pJoliet->RootDir.DirRec.cExtAttrBlocks = 0; 3308 pJoliet->RootDir.DirRec.offExtent.be = RT_H2BE_U32(pThis->Joliet.pRoot->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3309 pJoliet->RootDir.DirRec.offExtent.le = RT_H2LE_U32(pThis->Joliet.pRoot->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3310 pJoliet->RootDir.DirRec.cbData.be = RT_H2BE_U32(pThis->Joliet.pRoot->pDir->cbDir); 3311 pJoliet->RootDir.DirRec.cbData.le = RT_H2LE_U32(pThis->Joliet.pRoot->pDir->cbDir); 3312 rtFsIsoMakerTimespecToIso9660RecTimestamp(&pThis->Joliet.pRoot->pObj->BirthTime, &pJoliet->RootDir.DirRec.RecTime); 3313 pJoliet->RootDir.DirRec.fFileFlags = ISO9660_FILE_FLAGS_DIRECTORY; 3314 pJoliet->RootDir.DirRec.bFileUnitSize = 0; 3315 pJoliet->RootDir.DirRec.bInterleaveGapSize = 0; 3316 pJoliet->RootDir.DirRec.VolumeSeqNo.be = RT_H2BE_U16_C(1); 3317 pJoliet->RootDir.DirRec.VolumeSeqNo.le = RT_H2BE_U16_C(1); 3318 pJoliet->RootDir.DirRec.bFileIdLength = 1; 3319 pJoliet->RootDir.DirRec.achFileId[1] = 0x00; 3320 } 3321 3322 return VINF_SUCCESS; 3323 } 3324 3325 3326 /** 2866 3327 * Finalizes the image. 2867 3328 * … … 2876 3337 2877 3338 /* 2878 * Remove orphaned objects .3339 * Remove orphaned objects and allocate volume descriptors. 2879 3340 */ 2880 3341 int rc = rtFsIsoMakerFinalizeRemoveOrphans(pThis); 2881 3342 if (RT_FAILURE(rc)) 2882 3343 return rc; 2883 2884 /* 2885 * Allocate space for the volume descriptors. 2886 */ 2887 RTMemFree(pThis->pbVolDescs); 2888 pThis->pbVolDescs = (uint8_t *)RTMemAllocZ(pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE); 2889 AssertReturn(pThis->pbVolDescs, VERR_NO_MEMORY); 2890 2891 uint32_t offVolDescs = 0; 2892 2893 pThis->pPrimaryVolDesc = (PISO9660PRIMARYVOLDESC)&pThis->pbVolDescs[offVolDescs]; 2894 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 2895 2896 if (true) 2897 pThis->pElToritoDesc = NULL; 2898 else 2899 { 2900 pThis->pElToritoDesc = (PISO9660BOOTRECORD)&pThis->pbVolDescs[offVolDescs]; 2901 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 2902 } 2903 2904 if (!pThis->Joliet.uLevel) 2905 pThis->pJolietVolDesc = NULL; 2906 else 2907 { 2908 pThis->pJolietVolDesc = (PISO9660SUPVOLDESC)&pThis->pbVolDescs[offVolDescs]; 2909 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 2910 } 2911 2912 pThis->pTerminatorVolDesc = (PISO9660VOLDESCHDR)&pThis->pbVolDescs[offVolDescs]; 2913 offVolDescs += RTFSISOMAKER_SECTOR_SIZE; 2914 2915 if (pThis->Udf.uLevel > 0) 2916 { 2917 /** @todo UDF descriptors. */ 2918 } 2919 AssertReturn(offVolDescs == pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE, VERR_INTERNAL_ERROR_2); 3344 rc = rtFsIsoMakerFinalizePrepVolumeDescriptors(pThis); 3345 if (RT_FAILURE(rc)) 3346 return rc; 2920 3347 2921 3348 /*
Note:
See TracChangeset
for help on using the changeset viewer.