VirtualBox

儲存庫 vbox 的更動 67332


忽略:
時間撮記:
2017-6-11 下午02:35:05 (7 年 以前)
作者:
vboxsync
訊息:

IPRT: More ISO maker code.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67331 r67332  
    6565/** The sector size. */
    6666#define RTFSISOMAKER_SECTOR_SIZE            _2K
     67/** The sector offset mask. */
     68#define RTFSISOMAKER_SECTOR_OFFSET_MASK     (_2K - 1)
    6769/** Maximum number of objects. */
    6870#define RTFSISOMAKER_MAX_OBJECTS            _16M
     
    7274/** UTF-8 name buffer.  */
    7375#define RTFSISOMAKER_MAX_NAME_BUF           768
     76
     77/** TRANS.TBL left padding length.
     78 * We keep the amount of padding low to avoid wasing memory when generating
     79 * these long obsolete files. */
     80#define RTFSISOMAKER_TRANS_TBL_LEFT_PAD     12
    7481
    7582/** Tests if @a a_ch is in the set of d-characters. */
     
    207214    uint32_t                cHardlinks;
    208215
    209     /** The offset of the translate table file entry. */
    210     uint32_t                offTransTbl;
    211216    /** The offset of the directory entry in the parent directory. */
    212217    uint32_t                offDirRec;
     
    515520     * RTFSISOMAKERSRCTYPE_TRANS_TBL file. */
    516521    RTVFSFILE               hVfsSrcFile;
     522    /** Current directory hint. */
     523    PRTFSISOMAKERNAMEDIR    pDirHint;
    517524} RTFSISOMAKEROUTPUTFILE;
    518525/** Pointer to the instance data of an ISO maker output file. */
     
    16491656         * Add it to the directory.
    16501657         */
     1658        PRTFSISOMAKERNAME pTransTblNm;
    16511659        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pFile->Core, pDirName,
    1652                                     pNamespace->pszTransTbl, strlen(pNamespace->pszTransTbl), NULL /*ppNewName*/);
     1660                                    pNamespace->pszTransTbl, strlen(pNamespace->pszTransTbl), &pTransTblNm);
    16531661        if (RT_SUCCESS(rc))
     1662        {
     1663            pTransTblNm->cchTransNm = 0;
    16541664            return VINF_SUCCESS;
     1665        }
    16551666
    16561667        /*
     
    17471758            pName->pszTransNm           = pszDst;
    17481759            pName->cchSpecNm            = (uint16_t)cchSpec;
    1749             pName->cchRockRidgeNm       = 0;
    1750             pName->cchTransNm           = 0;
     1760            pName->cchRockRidgeNm       = (uint16_t)cchSpec;
     1761            pName->cchTransNm           = (uint16_t)cchSpec;
    17511762            pName->uDepth               = pParent->uDepth + 1;
    17521763            pName->fRockRidgeNmAlloced  = false;
     
    17591770            pName->INode                = pObj->idxObj;
    17601771            pName->cHardlinks           = 1;
    1761             pName->offTransTbl          = UINT32_MAX;
    17621772            pName->offDirRec            = UINT32_MAX;
    17631773            pName->cbDirRec             = 0;
     
    28152825 */
    28162826static int rtFsIsoMakerFinalizeIsoDirectoryEntry(PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, PRTFSISOMAKERNAME pName,
    2817                                                  uint32_t offInDir, uint32_t offInTransTbl, uint8_t uRootRockRidge)
     2827                                                 uint32_t offInDir, uint8_t uRootRockRidge)
    28182828{
    28192829    /* Set directory and translation table offsets.  (These are for
    28202830       helping generating data blocks later.) */
    28212831    pName->offDirRec   = offInDir;
    2822     pName->offTransTbl = offInTransTbl;
    28232832
    28242833    /* Calculate the minimal directory record size. */
     
    28812890         * Precalc the directory record size for the root directory.
    28822891         */
    2883         rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pNamespace->pRoot, 0 /*offInDir*/, 0 /*offInTransTbl*/,
    2884                                                    pNamespace->uRockRidgeLevel);
     2892        rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pNamespace->pRoot, 0 /*offInDir*/, pNamespace->uRockRidgeLevel);
    28852893        AssertRCReturn(rc, rc);
    28862894
     
    29022910
    29032911            /* Finalize the directory entries. */
    2904             uint32_t            offInTransTbl = 0;
    2905             uint32_t            cLeft         = pCurDir->cChildren;
    2906             PPRTFSISOMAKERNAME  ppChild       = pCurDir->papChildren;
     2912            uint32_t            cbTransTbl = 0;
     2913            uint32_t            cLeft       = pCurDir->cChildren;
     2914            PPRTFSISOMAKERNAME  ppChild     = pCurDir->papChildren;
    29072915            while (cLeft-- > 0)
    29082916            {
    29092917                PRTFSISOMAKERNAME pChild = *ppChild++;
    2910                 rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pChild, offInDir, offInTransTbl, 0 /*uRootRockRidge*/);
     2918                rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pChild, offInDir, 0 /*uRootRockRidge*/);
    29112919                AssertRCReturn(rc, rc);
    29122920
    29132921                offInDir += pChild->cbDirRec;
    29142922                if (pChild->cchTransNm)
    2915                     offInTransTbl += 2 /* type & space*/
    2916                                   +  RT_MAX(pChild->cchName, 39)
    2917                                   +  1 /* tab */
    2918                                   +  pChild->cchTransNm
    2919                                   +  1 /* newline */;
     2923                    cbTransTbl += 2 /* type & space*/
     2924                               +  RT_MAX(pChild->cchName, RTFSISOMAKER_TRANS_TBL_LEFT_PAD)
     2925                               +  1 /* tab */
     2926                               +  pChild->cchTransNm
     2927                               +  1 /* newline */;
    29202928            }
    29212929
     
    29272935            /* Set the translation table file size. */
    29282936            if (pCurDir->pTransTblFile)
    2929                 pCurDir->pTransTblFile->cbData = offInTransTbl;
     2937                pCurDir->pTransTblFile->cbData = cbTransTbl;
    29302938
    29312939            /* Add to the path table size calculation. */
     
    35523560        if (pChild->pszTransNm)
    35533561        {
    3554             /** @todo TRANS.TBL codeset, currently using UTF-8 which is probably not it. */
     3562            /** @todo TRANS.TBL codeset, currently using UTF-8 which is probably not it.
     3563             *        However, nobody uses this stuff any more, so who cares. */
    35553564            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);
     3565            size_t cchEntry = RTStrPrintf(szEntry, sizeof(szEntry), "%c %-*s\t%s\n", pChild->pDir ? 'D' : 'F',
     3566                                          RTFSISOMAKER_TRANS_TBL_LEFT_PAD, pChild->szName, pChild->pszTransNm);
    35583567            rc = RTVfsFileWrite(hVfsFile, szEntry, cchEntry, NULL);
    35593568            if (RT_FAILURE(rc))
     
    35833592
    35843593
     3594/**
     3595 * Reads file data.
     3596 *
     3597 * @returns IPRT status code
     3598 * @param   pThis           The instance data for the VFS file.  We use this to
     3599 *                          keep hints about where we are and we which source
     3600 *                          file we've opened/created.
     3601 * @param   pIsoMaker       The ISO maker instance.
     3602 * @param   offUnsigned     The ISO image byte offset of the requested data.
     3603 * @param   pbBuf           The output buffer.
     3604 * @param   cbBuf           How much to read.
     3605 * @param   pcbDone         Where to return how much was read.
     3606 */
    35853607static int rtFsIsoMakerOutFile_ReadFileData(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERINT pIsoMaker, uint64_t offUnsigned,
    35863608                                            uint8_t *pbBuf, size_t cbBuf, size_t *pcbDone)
     
    36723694            return rc;
    36733695        *pcbDone = cbToRead;
     3696
     3697        /*
     3698         * Check if we're into the zero padding at the end of the file now.
     3699         */
     3700        if (   cbToRead < cbBuf
     3701            && offInFile + cbToRead == pFile->cbData)
     3702        {
     3703            cbBuf -= cbToRead;
     3704            pbBuf += cbToRead;
     3705            size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - (pFile->cbData & RTFSISOMAKER_SECTOR_OFFSET_MASK));
     3706            memset(pbBuf, 0, cbZeros);
     3707            *pcbDone += cbZeros;
     3708        }
    36743709    }
    36753710    else
     
    36923727
    36933728
    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;
     3729static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, uint8_t *pbBuf)
     3730{
     3731    memset(pbBuf, pName->szName[0], sizeof(ISO9660DIRREC));
     3732    return pName->cbDirRec;
     3733}
     3734
     3735
     3736static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, uint32_t off, uint8_t *pbBuf, size_t cbBuf)
     3737{
     3738    Assert(off < pName->cbDirRec);
     3739
     3740    uint8_t abTmpBuf[256];
     3741    size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, pbBuf);
     3742    cbToCopy = RT_MIN(cbBuf, cbToCopy - off);
     3743    memcpy(pbBuf, &abTmpBuf[off], cbToCopy);
     3744    return (uint32_t)cbToCopy;
     3745}
     3746
     3747
     3748static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,
     3749                                                 uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf)
     3750{
     3751
     3752    /*
     3753     * Figure out which directory.  We keep a hint in the instance.
     3754     */
     3755    uint64_t             offInDir64;
     3756    PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint;
     3757    if (!pDir)
     3758    {
     3759        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3760        AssertReturn(pDir, 0);
     3761    }
     3762    if ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE))
     3763    { /* hit */ }
     3764    /* Seek forwards: */
     3765    else if (offUnsigned > pDir->offDir)
     3766        do
     3767        {
     3768            pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3769            AssertReturn(pDir, 0);
     3770        } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE));
     3771    /* Back to the start: */
     3772    else if (pFinalizedDirs->offDirs / RTFSISOMAKER_SECTOR_SIZE == offUnsigned / RTFSISOMAKER_SECTOR_SIZE)
     3773    {
     3774        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3775        AssertReturn(pDir, 0);
     3776    }
     3777    /* Seek backwards: */
     3778    else
     3779        do
     3780        {
     3781            pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3782            AssertReturn(pDir, 0);
     3783        } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE));
     3784
     3785    /*
     3786     * Update the hint.
     3787     */
     3788    pThis->pDirHint = pDir;
     3789
     3790    /*
     3791     * Generate content.
     3792     */
     3793    size_t cbDone = 0;
     3794    uint32_t offInDir = (uint32_t)offInDir64;
     3795    if (offInDir < pDir->cbDir)
     3796    {
     3797        PRTFSISOMAKERNAME   pDirName      = pDir->pName;
     3798        PRTFSISOMAKERNAME   pParentName   = pDirName->pParent ? pDirName->pParent : pDirName;
     3799        uint32_t            cbSpecialRecs = pDirName->cbDirRec + pParentName->cbDirRec;
     3800
     3801        /*
     3802         * Special '.' and/or '..' entries requested.
     3803         */
     3804        uint32_t iChild;
     3805        if (offInDir < cbSpecialRecs)
     3806        {
     3807            /* do '.' */
     3808            if (offInDir < pDirName->cbDirRec)
     3809            {
     3810                uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pDirName, offInDir, pbBuf, cbBuf);
     3811                cbDone   += cbCopied;
     3812                offInDir += cbCopied;
     3813                cbBuf    -= cbCopied;
     3814            }
     3815
     3816            /* do '..' */
     3817            if (cbBuf > 0)
     3818            {
     3819                uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pParentName, offInDir - pDirName->cbDirRec,
     3820                                                                              pbBuf, cbBuf);
     3821                cbDone   += cbCopied;
     3822                offInDir += cbCopied;
     3823                cbBuf    -= cbCopied;
     3824            }
     3825
     3826            iChild = 0;
     3827        }
     3828        /*
     3829         * Locate the directory entry we should start with.  We can do this
     3830         * using binary searching on offInDir.
     3831         */
     3832        else
     3833        {
     3834            /** @todo binary search   */
     3835            iChild = 0;
     3836            while (iChild < pDir->cChildren)
     3837            {
     3838                PRTFSISOMAKERNAME pChild = pDir->papChildren[iChild];
     3839                if ((offInDir - pChild->offDirRec) < pChild->cbDirRec)
     3840                    break;
     3841                iChild++;
     3842            }
     3843            AssertReturn(iChild < pDir->cChildren, 0);
     3844        }
     3845
     3846        /*
     3847         * Normal directory entries.
     3848         */
     3849        while (   cbBuf > 0
     3850               && iChild < pDir->cChildren)
     3851        {
     3852            PRTFSISOMAKERNAME pChild = pDir->papChildren[iChild];
     3853            uint32_t cbCopied;
     3854            if (   offInDir == pChild->offDirRec
     3855                && cbBuf    >= pChild->cbDirRec)
     3856                cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, pbBuf);
     3857            else
     3858                cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, offInDir - pChild->offDirRec, pbBuf, cbBuf);
     3859            cbDone   += cbCopied;
     3860            offInDir += cbCopied;
     3861            cbBuf    -= cbCopied;
     3862        }
     3863
     3864        /*
     3865         * Check if we're into the zero padding at the end of the directory now.
     3866         */
     3867        if (   cbBuf > 0
     3868            && iChild >= pDir->cChildren)
     3869        {
     3870            size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - (pDir->cbDir & RTFSISOMAKER_SECTOR_OFFSET_MASK));
     3871            memset(pbBuf, 0, cbZeros);
     3872            cbDone += cbZeros;
     3873        }
     3874    }
     3875    else
     3876    {
     3877        cbDone = RT_MIN(cbBuf, RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE) - offInDir);
     3878        memset(pbBuf, 0, cbDone);
     3879    }
     3880
     3881    return cbDone;
    37003882}
    37013883
     
    37063888{
    37073889    if (off < pFinalizedDirs->offPathTableL)
    3708         return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pNamespace, pFinalizedDirs, off, pbBuf, cbBuf);
     3890        return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, off, pbBuf, cbBuf);
    37093891    if (off < pFinalizedDirs->offPathTableM)
    37103892        return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, true /*fLittleEndian*/,
     
    40514233        pFileData->pFileHint   = NULL;
    40524234        pFileData->hVfsSrcFile = NIL_RTVFSFILE;
     4235        pFileData->pDirHint    = NULL;
    40534236        return VINF_SUCCESS;
    40544237    }
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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