VirtualBox

儲存庫 vbox 的更動 67519


忽略:
時間撮記:
2017-6-20 下午07:51:26 (7 年 以前)
作者:
vboxsync
訊息:

IPRT: More ISO maker code (import related).

檔案:
修改 1 筆資料

圖例:

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

    r67516 r67519  
    6767    /** The configuration index of the file. */
    6868    uint32_t                idxObj;
     69    /** Namespaces the file has been seen in already (RTFSISOMAKER_NAMESPACE_XXX). */
     70    uint32_t                fNamespaces;
     71    /** Pointer to the next file with the same block number. */
     72    struct RTFSISOMKIMPBLOCK2FILE *pNext;
    6973} RTFSISOMKIMPBLOCK2FILE;
    7074/** Pointer to a block-2-file translation node. */
     
    277281static DECLCALLBACK(int) rtFsIsoMakerImportDestroyData2File(PAVLU32NODECORE pNode, void *pvUser)
    278282{
     283    PRTFSISOMKIMPBLOCK2FILE pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)pNode;
     284    if (pBlock2File)
     285    {
     286        PRTFSISOMKIMPBLOCK2FILE pNext;
     287        while ((pNext = pBlock2File->pNext) != NULL)
     288        {
     289            pBlock2File->pNext = pNext->pNext;
     290            pNext->pNext = NULL;
     291            RTMemFree(pNext);
     292        }
     293        RTMemFree(pNode);
     294    }
     295
    279296    RT_NOREF(pvUser);
    280     RTMemFree(pNode);
     297    return VINF_SUCCESS;
     298}
     299
     300
     301/**
     302 * Adds a directory and names it given its ISO-9660 directory record and parent.
     303 *
     304 * @returns IPRT status code (safe to ignore).
     305 * @param   pThis               The importer instance.
     306 * @param   pDirRec             The directory record.
     307 * @param   fNamespace          The namespace flag.
     308 * @param   idxParent           Parent directory.
     309 * @param   pszName             The name.
     310 * @param   cDepth              The depth to add it with.
     311 * @param   pTodoList           The todo list (for directories).
     312 */
     313static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec,
     314                                                          uint32_t fNamespace, uint32_t idxParent, const char *pszName,
     315                                                          uint8_t cDepth, PRTLISTANCHOR pTodoList)
     316{
     317    Assert(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY);
     318    uint32_t idxObj;
     319    int rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, &idxObj);
     320    if (RT_SUCCESS(rc))
     321    {
     322        Log3(("  --> added directory #%#x\n", idxObj));
     323        pThis->pResults->cAddedDirs++;
     324
     325        /*
     326         * Enter the object into the namespace.
     327         */
     328        rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxParent, fNamespace, pszName);
     329        if (RT_SUCCESS(rc))
     330        {
     331            pThis->pResults->cAddedNames++;
     332
     333            /*
     334             * Push it onto the traversal stack.
     335             */
     336            PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir));
     337            if (pImpDir)
     338            {
     339                pImpDir->cbDir       = ISO9660_GET_ENDIAN(&pDirRec->cbData);
     340                pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
     341                pImpDir->idxObj      = idxObj;
     342                pImpDir->cDepth      = cDepth;
     343                RTListAppend(pTodoList, &pImpDir->Entry);
     344            }
     345            else
     346                rc = rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR");
     347        }
     348        else
     349            rc = rtFsIsoImpError(pThis, rc, "Error naming directory '%s'", pszName);
     350    }
     351    else
     352        rc = rtFsIsoImpError(pThis, rc, "Error adding directory '%s': %Rrc", pszName, pDirRec->fFileFlags, rc);
     353    return rc;
     354}
     355
     356
     357/**
     358 * Adds a file and names it given its ISO-9660 directory record and parent.
     359 *
     360 * @returns IPRT status code (safe to ignore).
     361 * @param   pThis               The importer instance.
     362 * @param   pDirRec             The directory record.
     363 * @param   fNamespace          The namespace flag.
     364 * @param   idxParent           Parent directory.
     365 * @param   pszName             The name.
     366 */
     367static int rtFsIsoImportProcessIso9660AddAndNameFile(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec,
     368                                                     uint32_t fNamespace, uint32_t idxParent, const char *pszName)
     369{
     370    int rc;
     371
     372    /*
     373     * First we must make sure the common source file has been added.
     374     */
     375    if (pThis->idxSrcFile != UINT32_MAX)
     376    { /* likely */ }
     377    else
     378    {
     379        rc = RTFsIsoMakerAddCommonSourceFile(pThis->hIsoMaker, pThis->hSrcFile, &pThis->idxSrcFile);
     380        if (RT_FAILURE(rc))
     381            return rtFsIsoImpError(pThis, rc, "RTFsIsoMakerAddCommonSourceFile failed: %Rrc", rc);
     382        Assert(pThis->idxSrcFile != UINT32_MAX);
     383    }
     384
     385    /*
     386     * Lookup the data block if the file has a non-zero length.   The aim is to
     387     * find files across namespaces while bearing in mind that files in the same
     388     * namespace may share data storage, i.e. what in a traditional unix file
     389     * system would be called hardlinked.  Problem is that the core engine doesn't
     390     * do hardlinking yet and assume each file has exactly one name per namespace.
     391     */
     392    uint32_t                idxObj          = UINT32_MAX;
     393    PRTFSISOMKIMPBLOCK2FILE pBlock2File     = NULL;
     394    PRTFSISOMKIMPBLOCK2FILE pBlock2FilePrev = NULL;
     395    if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0) /* no data tracking for zero byte files */
     396    {
     397        pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTAvlU32Get(&pThis->Block2FileRoot, ISO9660_GET_ENDIAN(&pDirRec->offExtent));
     398        if (pBlock2File)
     399        {
     400            if (!(pBlock2File->fNamespaces & fNamespace))
     401            {
     402                pBlock2File->fNamespaces |= fNamespace;
     403                idxObj = pBlock2File->idxObj;
     404            }
     405            else
     406            {
     407                do
     408                {
     409                    pBlock2FilePrev = pBlock2File;
     410                    pBlock2File = pBlock2File->pNext;
     411                } while (pBlock2File && (pBlock2File->fNamespaces & fNamespace));
     412                if (pBlock2File)
     413                {
     414                    pBlock2File->fNamespaces |= fNamespace;
     415                    idxObj = pBlock2File->idxObj;
     416                }
     417            }
     418        }
     419    }
     420
     421    /*
     422     * If the above lookup didn't succeed, add a new file with a lookup record.
     423     */
     424    if (idxObj == UINT32_MAX)
     425    {
     426        rc = RTFsIsoMakerAddUnnamedFileWithCommonSrc(pThis->hIsoMaker, pThis->idxSrcFile,
     427                                                     ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)ISO9660_SECTOR_SIZE,
     428                                                     ISO9660_GET_ENDIAN(&pDirRec->cbData), NULL /*pObjInfo*/, &idxObj);
     429        if (RT_FAILURE(rc))
     430            return rtFsIsoImpError(pThis, rc, "Error adding file '%s': %Rrc", pszName, rc);
     431        Assert(idxObj != UINT32_MAX);
     432
     433        /* Update statistics. */
     434        pThis->pResults->cAddedFiles++;
     435        if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0)
     436        {
     437            pThis->pResults->cbAddedDataBlocks += RT_ALIGN_32(ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_SECTOR_SIZE);
     438
     439            /* Lookup record. */
     440            pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTMemAlloc(sizeof(*pBlock2File));
     441            AssertReturn(pBlock2File, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPBLOCK2FILE"));
     442
     443            pBlock2File->idxObj      = idxObj;
     444            pBlock2File->Core.Key    = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
     445            pBlock2File->fNamespaces = fNamespace;
     446            pBlock2File->pNext       = NULL;
     447            if (!pBlock2FilePrev)
     448            {
     449                bool fRc = RTAvlU32Insert(&pThis->Block2FileRoot, &pBlock2File->Core);
     450                Assert(fRc); RT_NOREF(fRc);
     451            }
     452            else
     453            {
     454                pBlock2FilePrev->pNext = pBlock2File;
     455                pBlock2FilePrev->Core.pLeft  = NULL;
     456                pBlock2FilePrev->Core.pRight = NULL;
     457            }
     458        }
     459    }
     460
     461    /*
     462     * Enter the object into the namespace.
     463     */
     464    rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxParent, fNamespace, pszName);
     465    if (RT_SUCCESS(rc))
     466        pThis->pResults->cAddedNames++;
     467    else
     468        return rtFsIsoImpError(pThis, rc, "Error adding directory '%s': %Rrc", pszName, pDirRec->fFileFlags, rc);
    281469    return VINF_SUCCESS;
    282470}
     
    404592    Log3(("rtFsIsoImportProcessIso9660TreeWorker: Starting at @%#RX64 LB %#RX32 (out of %#RX32) in %#x\n",
    405593          off - cbChunk, cbChunk, cbChunk + cbDir, idxDir));
     594    const uint32_t fNamespace = fUnicode ? RTFSISOMAKER_NAMESPACE_JOLIET : RTFSISOMAKER_NAMESPACE_ISO_9660;
    406595    while (cbChunk > 0)
    407596    {
     
    522711                RT_NOREF(pbSys);
    523712            }
     713
    524714            /*
    525715             * Add the object.
    526716             */
    527             PRTFSISOMKIMPBLOCK2FILE pBlock2File = NULL;
    528             uint32_t                idxObj      = UINT32_MAX;
    529717            if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY)
    530             {
    531                 rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, &idxObj);
    532                 Log3(("  --> added directory #%#x\n", idxObj));
    533                 if (RT_SUCCESS(rc))
    534                     pThis->pResults->cAddedDirs++;
    535             }
     718                rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, fNamespace, idxDir,
     719                                                               pThis->szNameBuf, cDepth + 1, pTodoList);
    536720            else
    537             {
    538                 /* Add the common source file if we haven't done that already. */
    539                 if (pThis->idxSrcFile != UINT32_MAX)
    540                 { /* likely */ }
    541                 else
    542                 {
    543                     rc = RTFsIsoMakerAddCommonSourceFile(pThis->hIsoMaker, pThis->hSrcFile, &pThis->idxSrcFile);
    544                     if (RT_FAILURE(rc))
    545                         return rtFsIsoImpError(pThis, rc, "RTFsIsoMakerAddCommonSourceFile failed: %Rrc", rc);
    546                     Assert(pThis->idxSrcFile != UINT32_MAX);
    547                 }
    548 
    549                 if (ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0) /* no data tracking for zero byte files */
    550                     pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTAvlU32Get(&pThis->Block2FileRoot, ISO9660_GET_ENDIAN(&pDirRec->offExtent));
    551 /** @todo Check whether pBlock2File is already used in the current namespace as we don't
    552  * support hardlinking at present.  Seeing trouble with \dists\trusty\restricted\binary-i386\Packages.gz
    553  * on ubuntu-14.04.3-desktop-amd64.iso disappearing as it's probably identical
    554  * to g:\dists\trusty\main\binary-i386\Packages.gz. */
    555                 if (!pBlock2File)
    556                 {
    557                     rc = RTFsIsoMakerAddUnnamedFileWithCommonSrc(pThis->hIsoMaker, pThis->idxSrcFile,
    558                                                                  ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)ISO9660_SECTOR_SIZE,
    559                                                                  ISO9660_GET_ENDIAN(&pDirRec->cbData), NULL /*pObjInfo*/, &idxObj);
    560                     Log3(("  --> added new file #%#x\n", idxObj));
    561                     if (RT_SUCCESS(rc))
    562                     {
    563                         pThis->pResults->cAddedFiles++;
    564                         pThis->pResults->cbAddedDataBlocks += RT_ALIGN_32(ISO9660_GET_ENDIAN(&pDirRec->cbData), ISO9660_SECTOR_SIZE);
    565                     }
    566                 }
    567                 else
    568                 {
    569                     idxObj = pBlock2File->idxObj;
    570                     Log3(("  --> existing file #%#x'\n", idxObj));
    571                     rc = VINF_SUCCESS;
    572                 }
    573             }
    574 
    575             if (RT_SUCCESS(rc))
    576             {
    577                 /*
    578                  * Enter the object into the namespace.
    579                  */
    580                 rc = RTFsIsoMakerObjSetNameAndParent(pThis->hIsoMaker, idxObj, idxDir,
    581                                                      !fUnicode ? RTFSISOMAKER_NAMESPACE_ISO_9660 : RTFSISOMAKER_NAMESPACE_JOLIET,
    582                                                      pThis->szNameBuf);
    583                 if (RT_SUCCESS(rc))
    584                 {
    585                     pThis->pResults->cAddedNames++;
    586 
    587                     /*
    588                      * Remember the data location if this is a file, if it's a
    589                      * directory push it onto the traversal stack.
    590                      */
    591                     if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY)
    592                     {
    593                         PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir));
    594                         AssertReturn(pImpDir, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR"));
    595                         pImpDir->cbDir       = ISO9660_GET_ENDIAN(&pDirRec->cbData);
    596                         pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
    597                         pImpDir->idxObj      = idxObj;
    598                         pImpDir->cDepth      = cDepth + 1;
    599                         RTListAppend(pTodoList, &pImpDir->Entry);
    600                     }
    601                     else if (   !pBlock2File
    602                              && ISO9660_GET_ENDIAN(&pDirRec->cbData) > 0 /* no data tracking for zero byte files */)
    603                     {
    604                         pBlock2File = (PRTFSISOMKIMPBLOCK2FILE)RTMemAlloc(sizeof(*pBlock2File));
    605                         AssertReturn(pBlock2File, rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPBLOCK2FILE"));
    606                         pBlock2File->idxObj   = idxObj;
    607                         pBlock2File->Core.Key = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
    608                         bool fRc = RTAvlU32Insert(&pThis->Block2FileRoot, &pBlock2File->Core);
    609                         Assert(fRc); RT_NOREF(fRc);
    610                     }
    611                 }
    612                 else
    613                     rtFsIsoImpError(pThis, rc, "Invalid name at %#RX64: %.Rhxs",
    614                                     off - cbChunk, pDirRec->bFileIdLength, pDirRec->achFileId);
    615             }
    616             else
    617                 rtFsIsoImpError(pThis, rc, "Error adding '%s' (fFileFlags=%#x): %Rrc",
    618                                 pThis->szNameBuf, pDirRec->fFileFlags, rc);
     721                rtFsIsoImportProcessIso9660AddAndNameFile(pThis, pDirRec, fNamespace, idxDir, pThis->szNameBuf);
    619722        }
    620723        else
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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