Changeset 67331 in vbox
- Timestamp:
- Jun 10, 2017 12:42:09 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67330 r67331 509 509 /** The current file position. */ 510 510 uint64_t offCurPos; 511 /** Current file hint. */ 512 PRTFSISOMAKERFILE pFileHint; 513 /** Source file corresponding to pFileHint. 514 * This is used when dealing with a RTFSISOMAKERSRCTYPE_VFS_FILE or 515 * RTFSISOMAKERSRCTYPE_TRANS_TBL file. */ 516 RTVFSFILE hVfsSrcFile; 511 517 } RTFSISOMAKEROUTPUTFILE; 512 518 /** Pointer to the instance data of an ISO maker output file. */ … … 3016 3022 pCurFile->offData = *poffData; 3017 3023 *poffData += RT_ALIGN_64(pCurFile->cbData, RTFSISOMAKER_SECTOR_SIZE); 3024 RTListAppend(&pThis->FinalizedFiles, &pCurFile->FinalizedEntry); 3018 3025 } 3019 3026 } … … 3519 3526 3520 3527 /** 3528 * Produces the content of a TRANS.TBL file as a memory file. 3529 * 3530 * @returns IPRT status code. 3531 * @param pThis The ISO maker output file instance. The file is 3532 * returned as pThis->hVfsSrcFile. 3533 * @param pFile The TRANS.TBL file. 3534 */ 3535 static int rtFsIsoMakerOutFile_ProduceTransTbl(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFILE pFile) 3536 { 3537 /* 3538 * Create memory file instance. 3539 */ 3540 RTVFSFILE hVfsFile; 3541 int rc = RTVfsMemFileCreate(NIL_RTVFSIOSTREAM, pFile->cbData, &hVfsFile); 3542 AssertRCReturn(rc, rc); 3543 3544 /* 3545 * Produce the file content. 3546 */ 3547 PRTFSISOMAKERNAME *ppChild = pFile->u.pTransTblDir->pDir->papChildren; 3548 uint32_t cLeft = pFile->u.pTransTblDir->pDir->cChildren; 3549 while (cLeft-- > 0) 3550 { 3551 PRTFSISOMAKERNAME pChild = *ppChild++; 3552 if (pChild->pszTransNm) 3553 { 3554 /** @todo TRANS.TBL codeset, currently using UTF-8 which is probably not it. */ 3555 char szEntry[RTFSISOMAKER_MAX_NAME_BUF * 2 + 128]; 3556 size_t cchEntry = RTStrPrintf(szEntry, sizeof(szEntry), 3557 "%c %-38s\t%s\n", pChild->pDir ? 'D' : 'F', pChild->szName, pChild->pszTransNm); 3558 rc = RTVfsFileWrite(hVfsFile, szEntry, cchEntry, NULL); 3559 if (RT_FAILURE(rc)) 3560 { 3561 RTVfsFileRelease(hVfsFile); 3562 return rc; 3563 } 3564 } 3565 } 3566 3567 /* 3568 * Check that the size matches our estimate. 3569 */ 3570 uint64_t cbResult = 0; 3571 rc = RTVfsFileGetSize(hVfsFile, &cbResult); 3572 if (RT_SUCCESS(rc) && cbResult == pFile->cbData) 3573 { 3574 pThis->hVfsSrcFile = hVfsFile; 3575 return VINF_SUCCESS; 3576 } 3577 3578 AssertMsgFailed(("rc=%Rrc, cbResult=%#RX64 cbData=%#RX64\n", rc, cbResult, pFile->cbData)); 3579 RTVfsFileRelease(hVfsFile); 3580 return VERR_INTERNAL_ERROR_4; 3581 } 3582 3583 3584 3585 static int rtFsIsoMakerOutFile_ReadFileData(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERINT pIsoMaker, uint64_t offUnsigned, 3586 uint8_t *pbBuf, size_t cbBuf, size_t *pcbDone) 3587 { 3588 *pcbDone = 0; 3589 3590 /* 3591 * Figure out which file. We keep a hint in the instance. 3592 */ 3593 uint64_t offInFile; 3594 PRTFSISOMAKERFILE pFile = pThis->pFileHint; 3595 if (!pFile) 3596 { 3597 pFile = RTListGetFirst(&pIsoMaker->FinalizedFiles, RTFSISOMAKERFILE, FinalizedEntry); 3598 AssertReturn(pFile, VERR_INTERNAL_ERROR_2); 3599 } 3600 if ((offInFile = offUnsigned - pFile->offData) < RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE)) 3601 { /* hit */ } 3602 else if (offUnsigned > pFile->offData) 3603 { 3604 /* Seek forwards. */ 3605 do 3606 { 3607 pFile = RTListGetNext(&pIsoMaker->FinalizedFiles, pFile, RTFSISOMAKERFILE, FinalizedEntry); 3608 AssertReturn(pFile, VERR_INTERNAL_ERROR_3); 3609 } while ((offInFile = offUnsigned - pFile->offData) < RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE)); 3610 } 3611 else 3612 { 3613 /* Seek backwards. */ 3614 do 3615 { 3616 pFile = RTListGetPrev(&pIsoMaker->FinalizedFiles, pFile, RTFSISOMAKERFILE, FinalizedEntry); 3617 AssertReturn(pFile, VERR_INTERNAL_ERROR_3); 3618 } while ((offInFile = offUnsigned - pFile->offData) < RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE)); 3619 } 3620 3621 /* 3622 * Update the hint/current file. 3623 */ 3624 if (pThis->pFileHint != pFile) 3625 { 3626 pThis->pFileHint = pFile; 3627 if (pThis->hVfsSrcFile != NIL_RTVFSFILE) 3628 { 3629 RTVfsFileRelease(pThis->hVfsSrcFile); 3630 pThis->hVfsSrcFile = NIL_RTVFSFILE; 3631 } 3632 } 3633 3634 /* 3635 * Produce data bits according to the source type. 3636 */ 3637 if (offInFile < pFile->cbData) 3638 { 3639 int rc; 3640 size_t cbToRead = RT_MIN(cbBuf, pFile->cbData - offInFile); 3641 switch (pFile->enmSrcType) 3642 { 3643 case RTFSISOMAKERSRCTYPE_PATH: 3644 if (pThis->hVfsSrcFile == NIL_RTVFSFILE) 3645 { 3646 rc = RTVfsChainOpenFile(pFile->u.pszSrcPath, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 3647 &pThis->hVfsSrcFile, NULL, NULL); 3648 if (RT_FAILURE(rc)) 3649 return rc; 3650 } 3651 rc = RTVfsFileReadAt(pThis->hVfsSrcFile, offInFile, pbBuf, cbToRead, NULL); 3652 break; 3653 3654 case RTFSISOMAKERSRCTYPE_VFS_FILE: 3655 rc = RTVfsFileReadAt(pFile->u.hVfsFile, offInFile, pbBuf, cbToRead, NULL); 3656 break; 3657 3658 case RTFSISOMAKERSRCTYPE_TRANS_TBL: 3659 if (pThis->hVfsSrcFile == NIL_RTVFSFILE) 3660 { 3661 rc = rtFsIsoMakerOutFile_ProduceTransTbl(pThis, pFile); 3662 if (RT_FAILURE(rc)) 3663 return rc; 3664 } 3665 rc = RTVfsFileReadAt(pFile->u.hVfsFile, offInFile, pbBuf, cbToRead, NULL); 3666 break; 3667 3668 default: 3669 AssertFailedReturn(VERR_INTERNAL_ERROR_5); 3670 } 3671 if (RT_FAILURE(rc)) 3672 return rc; 3673 *pcbDone = cbToRead; 3674 } 3675 else 3676 { 3677 size_t cbZeros = RT_MIN(cbBuf, RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE) - offInFile); 3678 memset(pbBuf, 0, cbZeros); 3679 *pcbDone = cbZeros; 3680 } 3681 return VINF_SUCCESS; 3682 } 3683 3684 3685 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3686 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, bool fLittleEndian, 3687 uint32_t offInTable, uint8_t *pbBuf, size_t cbBuf) 3688 { 3689 RT_NOREF(pThis, pNamespace, pFinalizedDirs, fLittleEndian, offInTable, pbBuf, cbBuf); 3690 return 0; 3691 } 3692 3693 3694 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3695 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3696 uint64_t off, uint8_t *pbBuf, size_t cbBuf) 3697 { 3698 RT_NOREF(pThis, pNamespace, pFinalizedDirs, off, pbBuf, cbBuf); 3699 return 0; 3700 } 3701 3702 3703 static size_t rtFsIsoMakerOutFile_ReadDirStructures(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3704 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3705 uint64_t off, uint8_t *pbBuf, size_t cbBuf) 3706 { 3707 if (off < pFinalizedDirs->offPathTableL) 3708 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pNamespace, pFinalizedDirs, off, pbBuf, cbBuf); 3709 if (off < pFinalizedDirs->offPathTableM) 3710 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, true /*fLittleEndian*/, 3711 (uint32_t)(off - pFinalizedDirs->offPathTableL), pbBuf, cbBuf); 3712 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, false /*fLittleEndian*/, 3713 (uint32_t)(off - pFinalizedDirs->offPathTableM), pbBuf, cbBuf); 3714 } 3715 3716 3717 3718 /** 3521 3719 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 3522 3720 */ … … 3527 3725 size_t cbBuf = pSgBuf->paSegs[0].cbSeg; 3528 3726 uint8_t *pbBuf = (uint8_t *)pSgBuf->paSegs[0].pvSeg; 3529 size_t cbRead = 0; 3530 int rc; 3727 3531 3728 Assert(pSgBuf->cSegs == 1); 3532 3533 rc = VERR_NOT_IMPLEMENTED; 3534 RT_NOREF(pThis, pIsoMaker, cbBuf, pbBuf, off, fBlocking); 3729 RT_NOREF(fBlocking); 3730 3731 /* 3732 * Process the offset, checking for end-of-file. 3733 */ 3734 uint64_t offUnsigned; 3735 if (off < 0) 3736 offUnsigned = pThis->offCurPos; 3737 else 3738 offUnsigned = (uint64_t)off; 3739 if (offUnsigned >= pIsoMaker->cbFinalizedImage) 3740 { 3741 if (*pcbRead) 3742 { 3743 *pcbRead = 0; 3744 return VINF_EOF; 3745 } 3746 return VERR_EOF; 3747 } 3748 if ( !pcbRead 3749 && pIsoMaker->cbFinalizedImage - offUnsigned < cbBuf) 3750 return VERR_EOF; 3751 3752 /* 3753 * Produce the bytes. 3754 */ 3755 int rc = VINF_SUCCESS; 3756 size_t cbRead = 0; 3757 while (cbBuf > 0) 3758 { 3759 size_t cbDone; 3760 3761 /* Betting on there being more file data than metadata, thus doing the 3762 offset switch in decending order. */ 3763 if (offUnsigned >= pIsoMaker->offFirstFile) 3764 { 3765 if (offUnsigned < pIsoMaker->cbFinalizedImage) 3766 { 3767 rc = rtFsIsoMakerOutFile_ReadFileData(pThis, pIsoMaker, offUnsigned, pbBuf, cbBuf, &cbDone); 3768 if (RT_FAILURE(rc)) 3769 break; 3770 } 3771 else 3772 { 3773 rc = pcbRead ? VINF_EOF : VERR_EOF; 3774 break; 3775 } 3776 } 3777 /* 3778 * Joliet directory structures. 3779 */ 3780 else if ( offUnsigned >= pIsoMaker->JolietDirs.offDirs 3781 && pIsoMaker->JolietDirs.offDirs < pIsoMaker->JolietDirs.offPathTableL) 3782 cbDone = rtFsIsoMakerOutFile_ReadDirStructures(pThis, &pIsoMaker->Joliet, &pIsoMaker->JolietDirs, 3783 offUnsigned, pbBuf, cbBuf); 3784 /* 3785 * Primary ISO directory structures. 3786 */ 3787 else if (offUnsigned >= pIsoMaker->PrimaryIsoDirs.offDirs) 3788 cbDone = rtFsIsoMakerOutFile_ReadDirStructures(pThis, &pIsoMaker->PrimaryIso, &pIsoMaker->PrimaryIsoDirs, 3789 offUnsigned, pbBuf, cbBuf); 3790 /** @todo Insert El Torito stuff here? Probably okay to let it be in the file 3791 * area, right? */ 3792 /* 3793 * Volume descriptors. 3794 */ 3795 else if (offUnsigned >= _32K) 3796 { 3797 size_t offVolDescs = (size_t)offUnsigned - _32K; 3798 cbDone = RT_MIN(cbBuf, (pIsoMaker->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE) - offVolDescs); 3799 memcpy(pbBuf, &pIsoMaker->pbVolDescs[offVolDescs], cbDone); 3800 } 3801 /* 3802 * Zeros in the system area. 3803 */ 3804 else if (offUnsigned >= pIsoMaker->cbSysArea) 3805 { 3806 cbDone = RT_MIN(cbBuf, _32K - (size_t)offUnsigned); 3807 memset(pbBuf, 0, cbDone); 3808 } 3809 /* 3810 * Actual data in the system area. 3811 */ 3812 else 3813 { 3814 cbDone = RT_MIN(cbBuf, pIsoMaker->cbSysArea - (size_t)offUnsigned); 3815 memcpy(pbBuf, &pIsoMaker->pbSysArea[(size_t)offUnsigned], cbDone); 3816 } 3817 3818 /* 3819 * Common advance. 3820 */ 3821 cbRead += cbDone; 3822 offUnsigned += cbDone; 3823 pbBuf += cbDone; 3824 cbBuf -= cbDone; 3825 } 3535 3826 3536 3827 if (pcbRead) … … 3564 3855 */ 3565 3856 static DECLCALLBACK(int) rtFsIsoMakerOutFile_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, 3566 uint32_t *pfRetEvents)3857 uint32_t *pfRetEvents) 3567 3858 { 3568 3859 NOREF(pvThis); … … 3606 3897 */ 3607 3898 static DECLCALLBACK(int) rtFsIsoMakerOutFile_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 3608 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)3899 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 3609 3900 { 3610 3901 RT_NOREF(pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime); … … 3756 4047 if (RT_SUCCESS(rc)) 3757 4048 { 3758 pFileData->pIsoMaker = pThis; 3759 pFileData->offCurPos = 0; 4049 pFileData->pIsoMaker = pThis; 4050 pFileData->offCurPos = 0; 4051 pFileData->pFileHint = NULL; 4052 pFileData->hVfsSrcFile = NIL_RTVFSFILE; 3760 4053 return VINF_SUCCESS; 3761 4054 }
Note:
See TracChangeset
for help on using the changeset viewer.