VirtualBox

Changeset 67331 in vbox


Ignore:
Timestamp:
Jun 10, 2017 12:42:09 PM (8 years ago)
Author:
vboxsync
Message:

IPRT: More ISO maker code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67330 r67331  
    509509    /** The current file position. */
    510510    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;
    511517} RTFSISOMAKEROUTPUTFILE;
    512518/** Pointer to the instance data of an ISO maker output file. */
     
    30163022                pCurFile->offData = *poffData;
    30173023                *poffData += RT_ALIGN_64(pCurFile->cbData, RTFSISOMAKER_SECTOR_SIZE);
     3024                RTListAppend(&pThis->FinalizedFiles, &pCurFile->FinalizedEntry);
    30183025            }
    30193026        }
     
    35193526
    35203527/**
     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 */
     3535static 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
     3585static 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
     3685static 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
     3694static 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
     3703static 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/**
    35213719 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
    35223720 */
     
    35273725    size_t                  cbBuf     = pSgBuf->paSegs[0].cbSeg;
    35283726    uint8_t                *pbBuf     = (uint8_t *)pSgBuf->paSegs[0].pvSeg;
    3529     size_t                  cbRead    = 0;
    3530     int                     rc;
     3727
    35313728    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    }
    35353826
    35363827    if (pcbRead)
     
    35643855 */
    35653856static DECLCALLBACK(int) rtFsIsoMakerOutFile_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
    3566                                               uint32_t *pfRetEvents)
     3857                                                     uint32_t *pfRetEvents)
    35673858{
    35683859    NOREF(pvThis);
     
    36063897 */
    36073898static DECLCALLBACK(int) rtFsIsoMakerOutFile_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
    3608                                                PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
     3899                                                      PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
    36093900{
    36103901    RT_NOREF(pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime);
     
    37564047    if (RT_SUCCESS(rc))
    37574048    {
    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;
    37604053        return VINF_SUCCESS;
    37614054    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette