- Timestamp:
- Jun 20, 2017 1:10:56 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp
r67502 r67503 127 127 uint32_t idPrimaryVol; 128 128 129 /** Set if we've already seen a joliet volume descriptor. */ 130 bool fSeenJoliet; 131 129 132 /** Sector buffer for volume descriptors and such. */ 130 133 union … … 157 160 /** Import ISO contains more than one el torito descriptor. */ 158 161 #define VERR_ISOMK_IMPORT_MULTIPLE_EL_TORITO_DESCS (-24909) 162 /** Import ISO contains more than one joliet volume descriptor. */ 163 #define VERR_ISOMK_IMPORT_MULTIPLE_JOLIET_VOL_DESCS (-24908) 159 164 /** Import ISO starts with supplementary volume descriptor before any 160 165 * primary ones. */ 161 166 #define VERR_ISOMK_IMPORT_SUPPLEMENTARY_BEFORE_PRIMARY (-24909) 167 /** Import ISO contains an unsupported primary volume descriptor version. */ 168 #define VERR_IOSMK_IMPORT_PRIMARY_VOL_DESC_VER (-24909) 162 169 /** Import ISO contains a bad primary volume descriptor. */ 163 170 #define VERR_ISOMK_IMPORT_BAD_PRIMARY_VOL_DESC (-24910) 171 /** Import ISO contains an unsupported supplementary volume descriptor 172 * version. */ 173 #define VERR_IOSMK_IMPORT_SUP_VOL_DESC_VER (-24909) 174 /** Import ISO contains a bad supplementary volume descriptor. */ 175 #define VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC (-24910) 164 176 /** Import ISO uses a logical block size other than 2KB. */ 165 177 #define VERR_ISOMK_IMPORT_LOGICAL_BLOCK_SIZE_NOT_2KB (-24911) … … 168 180 /** Import ISO uses invalid volume sequence number. */ 169 181 #define VERR_ISOMK_IMPORT_INVALID_VOLUMNE_SEQ_NO (-24913) 182 /** Import ISO has different volume space sizes of primary and supplementary 183 * volume descriptors. */ 184 #define VERR_ISOMK_IMPORT_VOLUME_SPACE_SIZE_MISMATCH (-24913) 185 /** Import ISO has different volume set sizes of primary and supplementary 186 * volume descriptors. */ 187 #define VERR_ISOMK_IMPORT_VOLUME_IN_SET_MISMATCH (-24913) 170 188 /** Import ISO contains a bad root directory record. */ 171 189 #define VERR_ISOMK_IMPORT_BAD_ROOT_DIR_REC (-24914) … … 368 386 * Work our way thru all the directory records. 369 387 */ 388 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Starting at @%#RX64 LB %#zx\n", off - cbChunk, cbChunk)); 370 389 while (cbChunk > 0) 371 390 { … … 380 399 pDirRec = (PCISO9660DIRREC)memmove(&pThis->abBuf[ISO9660_SECTOR_SIZE - cbChunk], pDirRec, cbChunk); 381 400 401 Assert(!(off & (ISO9660_SECTOR_SIZE - 1))); 382 402 uint32_t cbToRead = RT_MIN(cbDir, sizeof(pThis->abBuf) - ISO9660_SECTOR_SIZE); 383 403 rc = RTVfsFileReadAt(pThis->hSrcFile, off, &pThis->abBuf[ISO9660_SECTOR_SIZE], cbToRead, NULL); … … 385 405 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", off, cbToRead); 386 406 407 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#zx\n", 408 cbToRead, off, off - cbChunk, cbChunk + cbToRead)); 387 409 off += cbToRead; 388 410 cbDir -= cbToRead; … … 401 423 if ( cbChunk <= UINT8_MAX 402 424 && cbDir == 0) 425 { 426 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> Restart loop\n")); 403 427 continue; 428 } 429 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> jumped to @%#RX64 LB %#zx\n", off - cbChunk, cbChunk)); 404 430 } 431 /* ASSUMES we're working in multiples of sectors! */ 432 else if (cbDir == 0) 433 break; 405 434 else 406 435 { 436 Assert(!(off & (ISO9660_SECTOR_SIZE - 1))); 407 437 uint32_t cbToRead = RT_MIN(cbDir, sizeof(pThis->abBuf)); 408 438 rc = RTVfsFileReadAt(pThis->hSrcFile, off, pThis->abBuf, cbToRead, NULL); … … 410 440 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", off, cbToRead); 411 441 442 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#zx\n", 443 cbToRead, off, off - cbChunk, cbChunk + cbToRead)); 412 444 off += cbToRead; 413 445 cbDir -= cbToRead; … … 421 453 * likely to get error with subsequent record too. 422 454 */ 423 Log3(("pDirRec=%p @%#010RX64 cb=%#04x ff=%#04x off=%#010RX32 cb=%#010RX32 id=%.*Rhxs\n", pDirRec, off - cbChunk, pDirRec->cbDirRec, pDirRec->fFileFlags, 424 ISO9660_GET_ENDIAN(&pDirRec->offExtent), ISO9660_GET_ENDIAN(&pDirRec->cbData), pDirRec->bFileIdLength, pDirRec->achFileId)); 455 uint8_t const cbSys = pDirRec->cbDirRec - RT_UOFFSETOF(ISO9660DIRREC, achFileId) 456 - pDirRec->bFileIdLength - !(pDirRec->bFileIdLength & 1); 457 uint8_t const * const pbSys = (uint8_t const *)&pDirRec->achFileId[pDirRec->bFileIdLength + !(pDirRec->bFileIdLength & 1)]; 458 Log3(("pDirRec=%p @%#010RX64 cb=%#04x ff=%#04x off=%#010RX32 cb=%#010RX32 cbSys=%#x id=%.*Rhxs\n", 459 pDirRec, off - cbChunk, pDirRec->cbDirRec, pDirRec->fFileFlags, ISO9660_GET_ENDIAN(&pDirRec->offExtent), 460 ISO9660_GET_ENDIAN(&pDirRec->cbData), cbSys, pDirRec->bFileIdLength, pDirRec->achFileId)); 425 461 rc = rtFsIsoImportValidateDirRec(pThis, pDirRec, cbChunk); 426 462 if (RT_FAILURE(rc)) … … 460 496 pThis->szNameBuf[cchName - offName] = '\0'; 461 497 } 498 Log3((" name='%s'\n", pThis->szNameBuf)); 462 499 463 500 /** @todo rock ridge. */ 464 501 if (cbSys > 0) 502 { 503 RT_NOREF(pbSys); 504 } 465 505 /* 466 506 * Add the object and enter it into the namespace. … … 553 593 * Make sure we've got a root in the namespace. 554 594 */ 555 uint32_t idxDir = RTFsIsoMakerGetObjIdxForPath(pThis->hIsoMaker, RTFSISOMAKER_NAMESPACE_ISO_9660, "/"); 595 uint32_t idxDir = RTFsIsoMakerGetObjIdxForPath(pThis->hIsoMaker, 596 !fUnicode ? RTFSISOMAKER_NAMESPACE_ISO_9660 : RTFSISOMAKER_NAMESPACE_JOLIET, 597 "/"); 556 598 if (idxDir == UINT32_MAX) 557 599 { 558 600 idxDir = RTFSISOMAKER_CFG_IDX_ROOT; 559 int rc = RTFsIsoMakerObjSetPath(pThis->hIsoMaker, RTFSISOMAKER_CFG_IDX_ROOT, RTFSISOMAKER_NAMESPACE_ISO_9660, "/"); 601 int rc = RTFsIsoMakerObjSetPath(pThis->hIsoMaker, RTFSISOMAKER_CFG_IDX_ROOT, 602 !fUnicode ? RTFSISOMAKER_NAMESPACE_ISO_9660 : RTFSISOMAKER_NAMESPACE_JOLIET, "/"); 560 603 if (RT_FAILURE(rc)) 561 604 return rtFsIsoImpError(pThis, rc, "RTFsIsoMakerObjSetPath failed on root dir: %Rrc", rc); … … 665 708 */ 666 709 if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION) 667 return rtFsIsoImpError(pThis, VERR_ VFS_UNSUPPORTED_FORMAT,710 return rtFsIsoImpError(pThis, VERR_IOSMK_IMPORT_PRIMARY_VOL_DESC_VER, 668 711 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion); 669 712 … … 730 773 731 774 732 static int rtFsIsoImportProcessSupplementaryDesc(PRTFSISOMKIMPORTER pThis, PISO9660SUPVOLDESC pSup) 733 { 734 RT_NOREF(pThis, pSup); 775 static int rtFsIsoImportProcessSupplementaryDesc(PRTFSISOMKIMPORTER pThis, PISO9660SUPVOLDESC pVolDesc) 776 { 777 /* 778 * Validate dual fields first. 779 */ 780 if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION) 781 return rtFsIsoImpError(pThis, VERR_IOSMK_IMPORT_SUP_VOL_DESC_VER, 782 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion); 783 784 if (RT_LE2H_U16(pVolDesc->cbLogicalBlock.le) != RT_BE2H_U16(pVolDesc->cbLogicalBlock.be)) 785 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC, 786 "Mismatching logical block size: {%#RX16,%#RX16}", 787 RT_BE2H_U16(pVolDesc->cbLogicalBlock.be), RT_LE2H_U16(pVolDesc->cbLogicalBlock.le)); 788 if (RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le) != RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be)) 789 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC, 790 "Mismatching volume space size: {%#RX32,%#RX32}", 791 RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le)); 792 if (RT_LE2H_U16(pVolDesc->cVolumesInSet.le) != RT_BE2H_U16(pVolDesc->cVolumesInSet.be)) 793 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC, 794 "Mismatching volumes in set: {%#RX16,%#RX16}", 795 RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le)); 796 if (RT_LE2H_U16(pVolDesc->VolumeSeqNo.le) != RT_BE2H_U16(pVolDesc->VolumeSeqNo.be)) 797 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC, 798 "Mismatching volume sequence no.: {%#RX16,%#RX16}", 799 RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le)); 800 if (RT_LE2H_U32(pVolDesc->cbPathTable.le) != RT_BE2H_U32(pVolDesc->cbPathTable.be)) 801 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_SUP_VOL_DESC, 802 "Mismatching path table size: {%#RX32,%#RX32}", 803 RT_BE2H_U32(pVolDesc->cbPathTable.be), RT_LE2H_U32(pVolDesc->cbPathTable.le)); 804 805 /* 806 * Validate field values against our expectations. 807 */ 808 if (ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock) != ISO9660_SECTOR_SIZE) 809 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_LOGICAL_BLOCK_SIZE_NOT_2KB, 810 "Unsupported block size: %#x", ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock)); 811 812 if (ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet) != pThis->cVolumesInSet) 813 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_VOLUME_IN_SET_MISMATCH, "Volumes in set: %#x, expected %#x", 814 ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet), pThis->cVolumesInSet); 815 816 if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo) != pThis->idPrimaryVol) 817 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_INVALID_VOLUMNE_SEQ_NO, 818 "Unexpected volume sequence number: %#x (expected %#x)", 819 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo), pThis->idPrimaryVol); 820 821 if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize) != pThis->cBlocksInPrimaryVolumeSpace) 822 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_INVALID_VOLUMNE_SEQ_NO, 823 "Volume space size differs between primary and supplementary descriptors: %#x, primary %#x", 824 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize), pThis->cBlocksInPrimaryVolumeSpace); 825 826 /* 827 * Validate the root directory record. 828 */ 829 int rc = rtFsIsoImportValidateRootDirRec(pThis, &pVolDesc->RootDir.DirRec); 830 if (RT_FAILURE(rc)) 831 return rc; 832 833 /* 834 * Is this a joliet descriptor? Ignore if not. 835 */ 836 uint8_t uJolietLevel = 0; 837 if ( pVolDesc->abEscapeSequences[0] == ISO9660_JOLIET_ESC_SEQ_0 838 && pVolDesc->abEscapeSequences[1] == ISO9660_JOLIET_ESC_SEQ_1) 839 switch (pVolDesc->abEscapeSequences[2]) 840 { 841 case ISO9660_JOLIET_ESC_SEQ_2_LEVEL_1: uJolietLevel = 1; break; 842 case ISO9660_JOLIET_ESC_SEQ_2_LEVEL_2: uJolietLevel = 2; break; 843 case ISO9660_JOLIET_ESC_SEQ_2_LEVEL_3: uJolietLevel = 3; break; 844 default: Log(("rtFsIsoImportProcessSupplementaryDesc: last joliet escape sequence byte doesn't match: %#x\n", 845 pVolDesc->abEscapeSequences[2])); 846 } 847 if (uJolietLevel == 0) 848 return VINF_SUCCESS; 849 850 /* 851 * Only one joliet descriptor. 852 */ 853 if (pThis->fSeenJoliet) 854 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MULTIPLE_JOLIET_VOL_DESCS, 855 "More than one Joliet volume descriptor is not supported"); 856 pThis->fSeenJoliet = true; 857 858 /* 859 * Process the directory tree. 860 */ 861 if (!(pThis->fFlags & RTFSISOMK_IMPORT_F_NO_JOLIET)) 862 return rtFsIsoImportProcessIso9660Tree(pThis, ISO9660_GET_ENDIAN(&pVolDesc->RootDir.DirRec.offExtent), 863 ISO9660_GET_ENDIAN(&pVolDesc->RootDir.DirRec.cbData), true /*fUnicode*/); 735 864 return VINF_SUCCESS; 736 865 } … … 790 919 pThis->idxSrcFile = UINT32_MAX; 791 920 //pThis->Block2FileRoot = NULL; 921 //pThis->cBlocksInPrimaryVolumeSpace = 0; 922 //pThis->cbPrimaryVolumeSpace = 0 923 //pThis->cVolumesInSet = 0; 924 //pThis->idPrimaryVol = 0; 925 //pThis->fSeenJoliet = false; 792 926 793 927 /*
Note:
See TracChangeset
for help on using the changeset viewer.