儲存庫 vbox 的更動 67571
圖例:
- 未更動
- 新增
- 刪除
-
trunk/include/iprt/err.h
r67538 r67571 2742 2742 /** Import ISO contains a bad directory record. */ 2743 2743 #define VERR_ISOMK_IMPORT_BAD_DIR_REC (-25124) 2744 /** Import ISO directory record with a mismatching volume sequence number. */ 2744 /** Import ISO contains a directory record with a mismatching volume sequence 2745 * number. */ 2745 2746 #define VERR_ISOMK_IMPORT_DIR_REC_VOLUME_SEQ_NO (-25125) 2746 /** Import ISO directory with an extent that is out of bounds. */2747 /** Import ISO contains a directory with an extent that is out of bounds. */ 2747 2748 #define VERR_ISOMK_IMPORT_DIR_REC_EXTENT_OUT_OF_BOUNDS (-25126) 2748 /** Import ISO directory with a bad record length. */2749 /** Import ISO contains a directory with a bad record length. */ 2749 2750 #define VERR_ISOMK_IMPORT_BAD_DIR_REC_LENGTH (-25127) 2750 /** Import ISO directory with a bad name length. */ 2751 /** Import ISO contains a '.' or '..' directory record with a bad name 2752 * length. */ 2751 2753 #define VERR_ISOMK_IMPORT_DOT_DIR_REC_BAD_NAME_LENGTH (-25128) 2752 /** Import ISO directorywith a bad name. */2754 /** Import ISO contains a '.' or '..' directory record with a bad name. */ 2753 2755 #define VERR_ISOMK_IMPORT_DOT_DIR_REC_BAD_NAME (-25129) 2756 /** Import ISO contains a directory with a more than one extent, that's 2757 * currently not supported. */ 2758 #define VERR_ISOMK_IMPORT_DIR_WITH_MORE_EXTENTS (-25130) 2759 /** Import ISO contains a multi-extent directory record that differs 2760 * significantly from first record. */ 2761 #define VERR_ISOMK_IMPORT_MISMATCHING_MULTI_EXTENT_REC (-25131) 2762 /** Import ISO contains a non-final multi-extent directory record with a 2763 * size that isn't block aligned. */ 2764 #define VERR_ISOMK_IMPORT_MISALIGNED_MULTI_EXTENT (-25132) 2765 /** Import ISO contains a non-contigiuous multi-extent data, this is 2766 * currently not supported. */ 2767 #define VERR_ISOMK_IMPORT_NON_CONTIGUOUS_MULTI_EXTENT (-25133) 2768 2754 2769 /** The boot catalog block in the import ISO is out of bounds. */ 2755 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_OUT_OF_BOUNDS (-251 30)2770 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_OUT_OF_BOUNDS (-25140) 2756 2771 /** The boot catalog block in the import ISO has an incorrect validation 2757 2772 * header ID. */ 2758 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_HEADER_ID (-251 31)2773 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_HEADER_ID (-25141) 2759 2774 /** The boot catalog validation entry in the import ISO has incorrect keys. */ 2760 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_KEYS (-251 32)2775 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_KEYS (-25142) 2761 2776 /** The boot catalog validation entry in the import ISO has an incorrect checksum. */ 2762 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_CHECKSUM (-251 33)2777 #define VERR_ISOMK_IMPORT_BOOT_CAT_BAD_VALIDATION_CHECKSUM (-25143) 2763 2778 /** A boot catalog entry in the import ISO has an unknown type. */ 2764 #define VERR_ISOMK_IMPORT_BOOT_CAT_UNKNOWN_HEADER_ID (-251 34)2779 #define VERR_ISOMK_IMPORT_BOOT_CAT_UNKNOWN_HEADER_ID (-25144) 2765 2780 /** A boot catalog entry in the import ISO has an invalid boot media type. */ 2766 #define VERR_ISOMK_IMPORT_BOOT_CAT_INVALID_BOOT_MEDIA_TYPE (-251 35)2781 #define VERR_ISOMK_IMPORT_BOOT_CAT_INVALID_BOOT_MEDIA_TYPE (-25145) 2767 2782 /** The default boot catalog entry in the import ISO has invalid flags set. */ 2768 #define VERR_ISOMK_IMPORT_BOOT_CAT_DEF_ENTRY_INVALID_FLAGS (-251 36)2783 #define VERR_ISOMK_IMPORT_BOOT_CAT_DEF_ENTRY_INVALID_FLAGS (-25146) 2769 2784 /** A boot catalog entry in the import ISO has reserved flag set. */ 2770 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_RESERVED_FLAG (-251 37)2785 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_RESERVED_FLAG (-25147) 2771 2786 /** A boot catalog entry in the import ISO is using the unused field. */ 2772 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_USES_UNUSED_FIELD (-251 38)2787 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_USES_UNUSED_FIELD (-25148) 2773 2788 /** A boot catalog entry in the import ISO points to a block after the end of 2774 2789 * the image input file. */ 2775 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_IMAGE_OUT_OF_BOUNDS (-251 39)2790 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_IMAGE_OUT_OF_BOUNDS (-25149) 2776 2791 /** A boot catalog entry in the import ISO has an image with an 2777 2792 * indeterminate size. */ 2778 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_UNKNOWN_IMAGE_SIZE (-251 40)2793 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_UNKNOWN_IMAGE_SIZE (-25150) 2779 2794 /** The boot catalog in the import ISO is larger than a sector or it is 2780 2795 * missing the final section header entry. */ 2781 #define VERR_ISOMK_IMPORT_BOOT_CAT_MISSING_FINAL_OR_TOO_BIG (-251 41)2796 #define VERR_ISOMK_IMPORT_BOOT_CAT_MISSING_FINAL_OR_TOO_BIG (-25151) 2782 2797 /** The default boot catalog entry in the import ISO an invalid boot 2783 2798 * indicator value. */ 2784 #define VERR_ISOMK_IMPORT_BOOT_CAT_DEF_ENTRY_INVALID_BOOT_IND (-251 42)2799 #define VERR_ISOMK_IMPORT_BOOT_CAT_DEF_ENTRY_INVALID_BOOT_IND (-25152) 2785 2800 /** A boot catalog extension entry in the import ISO was either flagged 2786 2801 * incorrectly in the previous entry or has an invalid header ID. */ 2787 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_INVALID_ID (-251 43)2802 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_INVALID_ID (-25153) 2788 2803 /** A boot catalog extension entry in the import ISO uses undefined flags 2789 2804 * which will be lost. */ 2790 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_UNDEFINED_FLAGS (-251 44)2805 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_UNDEFINED_FLAGS (-25154) 2791 2806 /** A boot catalog extension entry in the import ISO indicates more entries when 2792 2807 * we reached the end of the boot catalog sector. */ 2793 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_END_OF_SECTOR (-251 45)2808 #define VERR_ISOMK_IMPORT_BOOT_CAT_EXT_ENTRY_END_OF_SECTOR (-25155) 2794 2809 /** A boot catalog entry in the import ISO sets the continuation flag when using 2795 2810 * NONE as the selection criteria type. */ 2796 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_CONTINUATION_WITH_NONE (-251 46)2811 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_CONTINUATION_WITH_NONE (-25156) 2797 2812 /** A boot catalog entry in the import ISO sets the continuation flag when 2798 2813 * we reached the ned of the boot catalog secotr. */ 2799 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_CONTINUATION_EOS (-25147) 2814 #define VERR_ISOMK_IMPORT_BOOT_CAT_ENTRY_CONTINUATION_EOS (-25157) 2815 2800 2816 /** @} */ 2801 2817 -
trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp
r67549 r67571 239 239 * 240 240 * @returns IPRT status code (safe to ignore). 241 * @param pThis The importer instance. 242 * @param pDirRec The directory record. 243 * @param fNamespace The namespace flag. 244 * @param idxParent Parent directory. 245 * @param pszName The name. 246 * @param cDepth The depth to add it with. 247 * @param pTodoList The todo list (for directories). 248 */ 249 static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, 241 * @param pThis The importer instance. 242 * @param pDirRec The directory record. 243 * @param cbData The actual directory data size. (Always same as in the 244 * directory record, but this what we do for files below.) 245 * @param fNamespace The namespace flag. 246 * @param idxParent Parent directory. 247 * @param pszName The name. 248 * @param cDepth The depth to add it with. 249 * @param pTodoList The todo list (for directories). 250 */ 251 static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, uint64_t cbData, 250 252 uint32_t fNamespace, uint32_t idxParent, const char *pszName, 251 253 uint8_t cDepth, PRTLISTANCHOR pTodoList) … … 273 275 if (pImpDir) 274 276 { 275 pImpDir->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 277 Assert((uint32_t)cbData == cbData /* no multi-extents for dirs makes it this far */); 278 pImpDir->cbDir = (uint32_t)cbData; 276 279 pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent); 277 280 pImpDir->idxObj = idxObj; … … 295 298 * 296 299 * @returns IPRT status code (safe to ignore). 297 * @param pThis The importer instance. 298 * @param pDirRec The directory record. 299 * @param fNamespace The namespace flag. 300 * @param idxParent Parent directory. 301 * @param pszName The name. 302 */ 303 static int rtFsIsoImportProcessIso9660AddAndNameFile(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, 300 * @param pThis The importer instance. 301 * @param pDirRec The directory record. 302 * @param cbData The actual file data size. 303 * @param fNamespace The namespace flag. 304 * @param idxParent Parent directory. 305 * @param pszName The name. 306 */ 307 static int rtFsIsoImportProcessIso9660AddAndNameFile(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, uint64_t cbData, 304 308 uint32_t fNamespace, uint32_t idxParent, const char *pszName) 305 309 { … … 329 333 PRTFSISOMKIMPBLOCK2FILE pBlock2File = NULL; 330 334 PRTFSISOMKIMPBLOCK2FILE pBlock2FilePrev = NULL; 331 if ( ISO9660_GET_ENDIAN(&pDirRec->cbData)> 0) /* no data tracking for zero byte files */335 if (cbData > 0) /* no data tracking for zero byte files */ 332 336 { 333 337 pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTAvlU32Get(&pThis->Block2FileRoot, ISO9660_GET_ENDIAN(&pDirRec->offExtent)); … … 362 366 rc = RTFsIsoMakerAddUnnamedFileWithCommonSrc(pThis->hIsoMaker, pThis->idxSrcFile, 363 367 ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)ISO9660_SECTOR_SIZE, 364 ISO9660_GET_ENDIAN(&pDirRec->cbData), NULL /*pObjInfo*/, &idxObj);368 cbData, NULL /*pObjInfo*/, &idxObj); 365 369 if (RT_FAILURE(rc)) 366 370 return rtFsIsoImpError(pThis, rc, "Error adding file '%s': %Rrc", pszName, rc); … … 369 373 /* Update statistics. */ 370 374 pThis->pResults->cAddedFiles++; 371 if ( ISO9660_GET_ENDIAN(&pDirRec->cbData)> 0)372 { 373 pThis->pResults->cbAddedDataBlocks += RT_ALIGN_ 32(ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_SECTOR_SIZE);375 if (cbData > 0) 376 { 377 pThis->pResults->cbAddedDataBlocks += RT_ALIGN_64(cbData, ISO9660_SECTOR_SIZE); 374 378 375 379 /* Lookup record. */ … … 450 454 if (pDirRec->cbDirRec < RT_OFFSETOF(ISO9660DIRREC, achFileId) + pDirRec->bFileIdLength) 451 455 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_DIR_REC_LENGTH, 452 " Root dir record size is too small: %#x (min %#x)",456 "Dir record size is too small: %#x (min %#x)", 453 457 pDirRec->cbDirRec, RT_OFFSETOF(ISO9660DIRREC, achFileId) + pDirRec->bFileIdLength); 454 458 if (pDirRec->cbDirRec > cbMax) 455 459 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_DIR_REC_LENGTH, 456 "Root dir record size is too big: %#x (max %#x)", pDirRec->cbDirRec, cbMax); 460 "Dir record size is too big: %#x (max %#x)", pDirRec->cbDirRec, cbMax); 461 462 if ( (pDirRec->fFileFlags & (ISO9660_FILE_FLAGS_MULTI_EXTENT | ISO9660_FILE_FLAGS_DIRECTORY)) 463 == (ISO9660_FILE_FLAGS_MULTI_EXTENT | ISO9660_FILE_FLAGS_DIRECTORY)) 464 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_DIR_WITH_MORE_EXTENTS, 465 "Multi-extent directories are not supported (cbData=%#RX32 offExtent=%#RX32)", 466 ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_GET_ENDIAN(&pDirRec->offExtent)); 467 457 468 return VINF_SUCCESS; 458 469 } … … 464 475 * @returns IPRT status code (safe to ignore, see pThis->rc). 465 476 * @param pThis The importer instance. 466 * @param pDirRec The root directory record to validate.477 * @param pDirRec The dot directory record to validate. 467 478 * @param cbMax The maximum size. 468 479 * @param bName The name byte (0x00: '.', 0x01: '..'). … … 484 495 485 496 497 /** 498 * rtFsIsoImportProcessIso9660TreeWorker helper that reads more data. 499 * 500 * @returns IPRT status code. 501 * @param pThis The importer instance. 502 * @param ppDirRec Pointer to the directory record pointer (in/out). 503 * @param pcbChunk Pointer to the cbChunk variable (in/out). 504 * @param pcbDir Pointer to the cbDir variable (in/out). This indicates 505 * how much we've left to read from the directory. 506 * @param poffNext Pointer to the offNext variable (in/out). This 507 * indicates where the next chunk of directory data is in 508 * the input file. 509 */ 510 static int rtFsIsoImportProcessIso9660TreeWorkerReadMore(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC *ppDirRec, 511 uint32_t *pcbChunk, uint32_t *pcbDir, uint64_t *poffNext) 512 { 513 uint32_t cbChunk = *pcbChunk; 514 *ppDirRec = (PCISO9660DIRREC)memmove(&pThis->abBuf[ISO9660_SECTOR_SIZE - cbChunk], *ppDirRec, cbChunk); 515 516 Assert(!(*poffNext & (ISO9660_SECTOR_SIZE - 1))); 517 uint32_t cbToRead = RT_MIN(*pcbDir, sizeof(pThis->abBuf) - ISO9660_SECTOR_SIZE); 518 int rc = RTVfsFileReadAt(pThis->hSrcFile, *poffNext, &pThis->abBuf[ISO9660_SECTOR_SIZE], cbToRead, NULL); 519 if (RT_SUCCESS(rc)) 520 { 521 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#RX32\n", 522 cbToRead, *poffNext, *poffNext - cbChunk, cbChunk + cbToRead)); 523 *poffNext += cbToRead; 524 *pcbDir -= cbToRead; 525 *pcbChunk = cbChunk + cbToRead; 526 return VINF_SUCCESS; 527 } 528 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", *poffNext, cbToRead); 529 } 530 531 532 /** 533 * rtFsIsoImportProcessIso9660TreeWorker helper that deals with skipping to the 534 * next sector when cbDirRec is zero. 535 * 536 * @returns IPRT status code. 537 * @retval VERR_NO_MORE_FILES when we reaches the end of the directory. 538 * @param pThis The importer instance. 539 * @param ppDirRec Pointer to the directory record pointer (in/out). 540 * @param pcbChunk Pointer to the cbChunk variable (in/out). Indicates how 541 * much we've left to process starting and pDirRec. 542 * @param pcbDir Pointer to the cbDir variable (in/out). This indicates 543 * how much we've left to read from the directory. 544 * @param poffNext Pointer to the offNext variable (in/out). This 545 * indicates where the next chunk of directory data is in 546 * the input file. 547 */ 548 static int rtFsIsoImportProcessIso9660TreeWorkerHandleZeroSizedDirRec(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC *ppDirRec, 549 uint32_t *pcbChunk, uint32_t *pcbDir, uint64_t *poffNext) 550 { 551 uint32_t cbChunk = *pcbChunk; 552 uint64_t offChunk = *poffNext - cbChunk; 553 uint32_t cbSkip = ISO9660_SECTOR_SIZE - ((uint32_t)offChunk & (ISO9660_SECTOR_SIZE - 1)); 554 if (cbSkip < cbChunk) 555 { 556 *ppDirRec = (PCISO9660DIRREC)((uintptr_t)*ppDirRec + cbSkip); 557 *pcbChunk = cbChunk -= cbSkip; 558 if ( cbChunk > UINT8_MAX 559 || *pcbDir == 0) 560 { 561 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> jumped %#RX32 to @%#RX64 LB %#RX32\n", 562 cbSkip, *poffNext - cbChunk, cbChunk)); 563 return VINF_SUCCESS; 564 } 565 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> jumped %#RX32 to @%#RX64 LB %#RX32, but needs to read more\n", 566 cbSkip, *poffNext - cbChunk, cbChunk)); 567 return rtFsIsoImportProcessIso9660TreeWorkerReadMore(pThis, ppDirRec, pcbChunk, pcbDir, poffNext); 568 } 569 570 /* ASSUMES we're working in multiples of sectors! */ 571 if (*pcbDir == 0) 572 { 573 *pcbChunk = 0; 574 return VERR_NO_MORE_FILES; 575 } 576 577 /* End of chunk, read the next sectors. */ 578 Assert(!(*poffNext & (ISO9660_SECTOR_SIZE - 1))); 579 uint32_t cbToRead = RT_MIN(*pcbDir, sizeof(pThis->abBuf)); 580 int rc = RTVfsFileReadAt(pThis->hSrcFile, *poffNext, pThis->abBuf, cbToRead, NULL); 581 if (RT_SUCCESS(rc)) 582 { 583 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#RX32\n", 584 cbToRead, *poffNext, *poffNext - cbChunk, cbChunk + cbToRead)); 585 *poffNext += cbToRead; 586 *pcbDir -= cbToRead; 587 *pcbChunk = cbChunk + cbToRead; 588 *ppDirRec = (PCISO9660DIRREC)&pThis->abBuf[0]; 589 return VINF_SUCCESS; 590 } 591 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", *poffNext, cbToRead); 592 } 593 594 595 /** 596 * Deals with a single directory. 597 * 598 * @returns IPRT status code (safe to ignore, see pThis->rc). 599 * @param pThis The importer instance. 600 * @param idxDir The configuration index for the directory. 601 * @param offDirBlock The offset of the directory data. 602 * @param cbDir The size of the directory data. 603 * @param cDepth The depth of the directory. 604 * @param fUnicode Set if it's a unicode (UTF-16BE) encoded 605 * directory. 606 * @param pTodoList The todo-list to add sub-directories to. 607 */ 486 608 static int rtFsIsoImportProcessIso9660TreeWorker(PRTFSISOMKIMPORTER pThis, uint32_t idxDir, 487 609 uint32_t offDirBlock, uint32_t cbDir, uint8_t cDepth, bool fUnicode, … … 498 620 */ 499 621 uint32_t cbChunk = RT_MIN(cbDir, sizeof(pThis->abBuf)); 500 uint64_t off 501 int rc = RTVfsFileReadAt(pThis->hSrcFile, off , pThis->abBuf, cbChunk, NULL);622 uint64_t offNext = (uint64_t)offDirBlock * ISO9660_SECTOR_SIZE; 623 int rc = RTVfsFileReadAt(pThis->hSrcFile, offNext, pThis->abBuf, cbChunk, NULL); 502 624 if (RT_FAILURE(rc)) 503 return rtFsIsoImpError(pThis, rc, "Error reading directory at %#RX64 (%#RX32 / %#RX32): %Rrc", off , cbChunk, cbDir);504 505 cbDir -= cbChunk;506 off 625 return rtFsIsoImpError(pThis, rc, "Error reading directory at %#RX64 (%#RX32 / %#RX32): %Rrc", offNext, cbChunk, cbDir); 626 627 cbDir -= cbChunk; 628 offNext += cbChunk; 507 629 508 630 /* … … 527 649 */ 528 650 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Starting at @%#RX64 LB %#RX32 (out of %#RX32) in %#x\n", 529 off - cbChunk, cbChunk, cbChunk + cbDir, idxDir));651 offNext - cbChunk, cbChunk, cbChunk + cbDir, idxDir)); 530 652 const uint32_t fNamespace = fUnicode ? RTFSISOMAKER_NAMESPACE_JOLIET : RTFSISOMAKER_NAMESPACE_ISO_9660; 531 while (cbChunk > 0) 653 while ( cbChunk > 0 654 || cbDir > 0) 532 655 { 533 656 /* … … 539 662 else 540 663 { 541 pDirRec = (PCISO9660DIRREC)memmove(&pThis->abBuf[ISO9660_SECTOR_SIZE - cbChunk], pDirRec, cbChunk); 542 543 Assert(!(off & (ISO9660_SECTOR_SIZE - 1))); 544 uint32_t cbToRead = RT_MIN(cbDir, sizeof(pThis->abBuf) - ISO9660_SECTOR_SIZE); 545 rc = RTVfsFileReadAt(pThis->hSrcFile, off, &pThis->abBuf[ISO9660_SECTOR_SIZE], cbToRead, NULL); 664 rc = rtFsIsoImportProcessIso9660TreeWorkerReadMore(pThis, &pDirRec, &cbChunk, &cbDir, &offNext); 546 665 if (RT_FAILURE(rc)) 547 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", off, cbToRead); 548 549 Log3(("rtFsIsoImportProcessIso9660TreeWorker: Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#RX32\n", 550 cbToRead, off, off - cbChunk, cbChunk + cbToRead)); 551 off += cbToRead; 552 cbDir -= cbToRead; 553 cbChunk += cbToRead; 666 return rc; 554 667 } 555 668 556 669 /* If null length, skip to the next sector. May have to read some then. */ 557 if (pDirRec->cbDirRec == 0) 558 { 559 uint64_t offChunk = off - cbChunk; 560 uint32_t cbSkip = ISO9660_SECTOR_SIZE - ((uint32_t)offChunk & (ISO9660_SECTOR_SIZE - 1)); 561 if (cbSkip < cbChunk) 670 if (pDirRec->cbDirRec != 0) 671 { /* likely */ } 672 else 673 { 674 rc = rtFsIsoImportProcessIso9660TreeWorkerHandleZeroSizedDirRec(pThis, &pDirRec, &cbChunk, &cbDir, &offNext); 675 if (RT_FAILURE(rc)) 562 676 { 563 pDirRec = (PCISO9660DIRREC)((uintptr_t)pDirRec + cbSkip); 564 cbChunk -= cbSkip; 565 if ( cbChunk <= UINT8_MAX 566 && cbDir == 0) 567 { 568 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> Restart loop\n")); 569 continue; 570 } 571 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> jumped %#RX32 to @%#RX64 LB %#RX32\n", 572 cbSkip, off - cbChunk, cbChunk)); 677 if (rc == VERR_NO_MORE_FILES) 678 break; 679 return rc; 573 680 } 574 /* ASSUMES we're working in multiples of sectors! */ 575 else if (cbDir == 0) 576 break; 577 else 578 { 579 Assert(!(off & (ISO9660_SECTOR_SIZE - 1))); 580 uint32_t cbToRead = RT_MIN(cbDir, sizeof(pThis->abBuf)); 581 rc = RTVfsFileReadAt(pThis->hSrcFile, off, pThis->abBuf, cbToRead, NULL); 582 if (RT_FAILURE(rc)) 583 return rtFsIsoImpError(pThis, rc, "Error reading %#RX32 bytes at %#RX64 (dir): %Rrc", off, cbToRead); 584 585 Log3(("rtFsIsoImportProcessIso9660TreeWorker: cbDirRec=0 --> Read %#zx more bytes @%#RX64, now got @%#RX64 LB %#RX32\n", 586 cbToRead, off, off - cbChunk, cbChunk + cbToRead)); 587 off += cbToRead; 588 cbDir -= cbToRead; 589 cbChunk += cbToRead; 590 pDirRec = (PCISO9660DIRREC)&pThis->abBuf[0]; 591 } 681 if (pDirRec->cbDirRec == 0) 682 continue; 592 683 } 593 684 … … 600 691 uint8_t const * const pbSys = (uint8_t const *)&pDirRec->achFileId[pDirRec->bFileIdLength + !(pDirRec->bFileIdLength & 1)]; 601 692 Log3(("pDirRec=&abBuf[%#07zx]: @%#010RX64 cb=%#04x ff=%#04x off=%#010RX32 cb=%#010RX32 cbSys=%#x id=%.*Rhxs\n", 602 (uintptr_t)pDirRec - (uintptr_t)&pThis->abBuf[0], off - cbChunk, pDirRec->cbDirRec, pDirRec->fFileFlags,693 (uintptr_t)pDirRec - (uintptr_t)&pThis->abBuf[0], offNext - cbChunk, pDirRec->cbDirRec, pDirRec->fFileFlags, 603 694 ISO9660_GET_ENDIAN(&pDirRec->offExtent), ISO9660_GET_ENDIAN(&pDirRec->cbData), cbSys, 604 695 pDirRec->bFileIdLength, pDirRec->achFileId)); … … 606 697 if (RT_FAILURE(rc)) 607 698 return rc; 699 700 /* This early calculation of the next record is due to multi-extent 701 handling further down. */ 702 uint32_t cbChunkNew = cbChunk - pDirRec->cbDirRec; 703 PCISO9660DIRREC pDirRecNext = (PCISO9660DIRREC)((uintptr_t)pDirRec + pDirRec->cbDirRec); 608 704 609 705 /* … … 649 745 650 746 /* 651 * Add the object. 747 * Deal with multi-extent files (usually large ones). We currently only 748 * handle files where the data is in single continuous chunk and only split 749 * up into multiple directory records because of data type limitations. 652 750 */ 653 if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY) 654 rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, fNamespace, idxDir, 655 pThis->szNameBuf, cDepth + 1, pTodoList); 751 uint8_t abDirRecCopy[256]; 752 uint64_t cbData = ISO9660_GET_ENDIAN(&pDirRec->cbData); 753 if (!(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT)) 754 { /* likely */ } 656 755 else 657 rtFsIsoImportProcessIso9660AddAndNameFile(pThis, pDirRec, fNamespace, idxDir, pThis->szNameBuf); 756 { 757 if (cbData & (ISO9660_SECTOR_SIZE - 1)) 758 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MISALIGNED_MULTI_EXTENT, 759 "The size of non-final multi-extent record #0x0 isn't block aligned: %#RX64", cbData); 760 761 /* Make a copy of the first directory record so we don't overwrite 762 it when reading in more records below. */ 763 pDirRec = (PCISO9660DIRREC)memcpy(abDirRecCopy, pDirRec, pDirRec->cbDirRec); 764 765 /* Process extent records. */ 766 uint32_t cDirRecs = 1; 767 uint32_t offNextBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent) 768 + ISO9660_GET_ENDIAN(&pDirRec->cbData) / ISO9660_SECTOR_SIZE; 769 while ( cbChunkNew > 0 770 || cbDir > 0) 771 { 772 /* Read more? Skip? */ 773 if ( cbChunkNew <= UINT8_MAX 774 && cbDir != 0) 775 { 776 rc = rtFsIsoImportProcessIso9660TreeWorkerReadMore(pThis, &pDirRecNext, &cbChunkNew, &cbDir, &offNext); 777 if (RT_FAILURE(rc)) 778 return rc; 779 } 780 if (pDirRecNext->cbDirRec == 0) 781 { 782 rc = rtFsIsoImportProcessIso9660TreeWorkerHandleZeroSizedDirRec(pThis, &pDirRecNext, &cbChunkNew, 783 &cbDir, &offNext); 784 if (RT_FAILURE(rc)) 785 { 786 if (rc == VERR_NO_MORE_FILES) 787 break; 788 return rc; 789 } 790 if (pDirRecNext->cbDirRec == 0) 791 continue; 792 } 793 794 /* Check the next record. */ 795 rc = rtFsIsoImportValidateDirRec(pThis, pDirRecNext, cbChunkNew); 796 if (RT_FAILURE(rc)) 797 return rc; 798 if (pDirRecNext->bFileIdLength != pDirRec->bFileIdLength) 799 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MISMATCHING_MULTI_EXTENT_REC, 800 "Multi-extent record #%#x differs from the first: bFileIdLength is %#x, expected %#x", 801 cDirRecs, pDirRecNext->bFileIdLength, pDirRec->bFileIdLength); 802 if (memcmp(pDirRecNext->achFileId, pDirRec->achFileId, pDirRec->bFileIdLength) != 0) 803 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MISMATCHING_MULTI_EXTENT_REC, 804 "Multi-extent record #%#x differs from the first: achFileId is %.*Rhxs, expected %.*Rhxs", 805 cDirRecs, pDirRecNext->bFileIdLength, pDirRecNext->achFileId, 806 pDirRec->bFileIdLength, pDirRec->achFileId); 807 if (ISO9660_GET_ENDIAN(&pDirRecNext->VolumeSeqNo) != ISO9660_GET_ENDIAN(&pDirRec->VolumeSeqNo)) 808 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MISMATCHING_MULTI_EXTENT_REC, 809 "Multi-extent record #%#x differs from the first: VolumeSeqNo is %#x, expected %#x", 810 cDirRecs, ISO9660_GET_ENDIAN(&pDirRecNext->VolumeSeqNo), 811 ISO9660_GET_ENDIAN(&pDirRec->VolumeSeqNo)); 812 if ( (pDirRecNext->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT) 813 && (ISO9660_GET_ENDIAN(&pDirRecNext->cbData) & (ISO9660_SECTOR_SIZE - 1)) ) 814 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_MISALIGNED_MULTI_EXTENT, 815 "The size of non-final multi-extent record #%#x isn't block aligned: %#RX32", 816 cDirRecs, ISO9660_GET_ENDIAN(&pDirRecNext->cbData)); 817 818 /* Check that the data is contiguous, then add the data. */ 819 if (ISO9660_GET_ENDIAN(&pDirRecNext->offExtent) == offNextBlock) 820 cbData += ISO9660_GET_ENDIAN(&pDirRecNext->cbData); 821 else 822 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_NON_CONTIGUOUS_MULTI_EXTENT, 823 "Multi-extent record #%#x isn't contiguous: offExtent=%#RX32, expected %#RX32", 824 cDirRecs, ISO9660_GET_ENDIAN(&pDirRecNext->offExtent), offNextBlock); 825 826 /* Advance. */ 827 cDirRecs++; 828 bool fDone = !(pDirRecNext->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT); 829 offNext += ISO9660_GET_ENDIAN(&pDirRecNext->cbData) / ISO9660_SECTOR_SIZE; 830 cbChunkNew -= pDirRecNext->cbDirRec; 831 pDirRecNext = (PCISO9660DIRREC)((uintptr_t)pDirRecNext + pDirRecNext->cbDirRec); 832 if (fDone) 833 break; 834 } 835 } 836 if (RT_SUCCESS(rc)) 837 { 838 /* 839 * Add the object. 840 */ 841 if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY) 842 rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, cbData, fNamespace, idxDir, 843 pThis->szNameBuf, cDepth + 1, pTodoList); 844 else 845 rtFsIsoImportProcessIso9660AddAndNameFile(pThis, pDirRec, cbData, fNamespace, idxDir, pThis->szNameBuf); 846 } 658 847 } 659 848 else 660 849 rtFsIsoImpError(pThis, rc, "Invalid name at %#RX64: %.Rhxs", 661 off - cbChunk, pDirRec->bFileIdLength, pDirRec->achFileId);850 offNext - cbChunk, pDirRec->bFileIdLength, pDirRec->achFileId); 662 851 663 852 /* 664 853 * Advance to the next directory record. 665 854 */ 666 cbChunk -= pDirRec->cbDirRec;667 pDirRec = (PCISO9660DIRREC)((uintptr_t)pDirRec + pDirRec->cbDirRec);855 cbChunk = cbChunkNew; 856 pDirRec = pDirRecNext; 668 857 } 669 858 … … 672 861 673 862 863 /** 864 * Deals with a directory tree. 865 * 866 * This is implemented by tracking directories that needs to be processed in a 867 * todo list, so no recursive calls, however it uses a bit of heap. 868 * 869 * @returns IPRT status code (safe to ignore, see pThis->rc). 870 * @param pThis The importer instance. 871 * @param offDirBlock The offset of the root directory data. 872 * @param cbDir The size of the root directory data. 873 * @param fUnicode Set if it's a unicode (UTF-16BE) encoded 874 * directory. 875 */ 674 876 static int rtFsIsoImportProcessIso9660Tree(PRTFSISOMKIMPORTER pThis, uint32_t offDirBlock, uint32_t cbDir, bool fUnicode) 675 877 {
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器