VirtualBox

Changeset 67794 in vbox


Ignore:
Timestamp:
Jul 5, 2017 12:29:35 PM (7 years ago)
Author:
vboxsync
Message:

isomaker: Added API for setting the rock ridge name and adjusted RTFsIsoMakerAddUnnamedDir to take additional attributes.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/formats/iso9660.h

    r67790 r67794  
    12371237/** Reserved / historically was uname network node name. */
    12381238#define ISO9660RRIP_SL_C_UNAME          UINT8_C(0x20)
    1239 /** Reserved mask (includes historically bits). */
     1239/** Reserved mask (considers historically bits reserved). */
    12401240#define ISO9660RRIP_SL_C_RESERVED_MASK  UINT8_C(0xf0)
    12411241/** @} */
     
    12731273/** Reserved / historically was uname network node name. */
    12741274#define ISO9660RRIP_NM_F_UNAME          UINT8_C(0x20)
     1275/** Reserved mask (considers historically bits reserved). */
     1276#define ISO9660RRIP_NM_F_RESERVED_MASK  UINT8_C(0xf8)
    12751277/** @} */
    12761278
  • trunk/include/iprt/fsisomaker.h

    r67549 r67794  
    252252
    253253/**
     254 * Changes the rock ridge name for the object in the selected namespaces.
     255 *
     256 * The object must already be enetered into the namespaces by
     257 * RTFsIsoMakerObjSetNameAndParent, RTFsIsoMakerObjSetPath or similar.
     258 *
     259 * @returns IPRT status code.
     260 * @param   hIsoMaker           The ISO maker handle.
     261 * @param   idxObj              The configuration index of to name.
     262 * @param   fNamespaces         The namespaces to apply the path to
     263 *                              (RTFSISOMAKER_NAMESPACE_XXX).
     264 * @param   pszRockName         The rock ridge name.  Passing NULL or an empty
     265 *                              string will restore the specified name.
     266 */
     267RTDECL(int) RTFsIsoMakerObjSetRockName(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszRockName);
     268
     269/**
    254270 * Enables or disable syslinux boot info table patching of a file.
    255271 *
     
    280296 * @returns IPRT status code
    281297 * @param   hIsoMaker           The ISO maker handle.
     298 * @param   pObjInfo            Pointer to object attributes, must be set to
     299 *                              UNIX.  The size and hardlink counts are ignored.
     300 *                              Optional.
    282301 * @param   pidxObj             Where to return the configuration index of the
    283302 *                              directory.
    284303 * @sa      RTFsIsoMakerAddDir, RTFsIsoMakerObjSetPath
    285304 */
    286 RTDECL(int) RTFsIsoMakerAddUnnamedDir(RTFSISOMAKER hIsoMaker, uint32_t *pidxObj);
     305RTDECL(int) RTFsIsoMakerAddUnnamedDir(RTFSISOMAKER hIsoMaker, PCRTFSOBJINFO pObjInfo, uint32_t *pidxObj);
    287306
    288307/**
  • trunk/include/iprt/mangling.h

    r67598 r67794  
    941941# define RTFsIsoMakerObjSetPath                         RT_MANGLER(RTFsIsoMakerObjSetPath)
    942942# define RTFsIsoMakerObjSetNameAndParent                RT_MANGLER(RTFsIsoMakerObjSetNameAndParent)
     943# define RTFsIsoMakerObjSetRockName                     RT_MANGLER(RTFsIsoMakerObjSetRockName)
    943944# define RTFsIsoMakerAddUnnamedDir                      RT_MANGLER(RTFsIsoMakerAddUnnamedDir)
    944945# define RTFsIsoMakerAddDir                             RT_MANGLER(RTFsIsoMakerAddDir)
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67605 r67794  
    649649                                  PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec, PPRTFSISOMAKERNAME ppNewName);
    650650static int rtFsIsoMakerObjUnsetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj);
    651 static int rtFsIsoMakerAddUnnamedDirWorker(PRTFSISOMAKERINT pThis, PRTFSISOMAKERDIR *ppDir);
     651static int rtFsIsoMakerAddUnnamedDirWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, PRTFSISOMAKERDIR *ppDir);
    652652static int rtFsIsoMakerAddUnnamedFileWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, size_t cbExtra,
    653653                                            PRTFSISOMAKERFILE *ppFile);
     
    811811         */
    812812        PRTFSISOMAKERDIR pDirRoot;
    813         rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pDirRoot);
     813        rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, NULL /*pObjInfo*/, &pDirRoot);
    814814        if (RT_SUCCESS(rc))
    815815        {
     
    22012201                if (!pChild)
    22022202                {
    2203                     rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pChildObj);
     2203                    rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, NULL /*pObjInfo*/, &pChildObj);
    22042204                    if (RT_SUCCESS(rc))
    22052205                        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, pParent, pszPath, cchComponent, &pChild);
     
    26172617
    26182618/**
     2619 * Changes the rock ridge name for the object in the selected namespaces.
     2620 *
     2621 * The object must already be enetered into the namespaces by
     2622 * RTFsIsoMakerObjSetNameAndParent, RTFsIsoMakerObjSetPath or similar.
     2623 *
     2624 * @returns IPRT status code.
     2625 * @param   hIsoMaker           The ISO maker handle.
     2626 * @param   idxObj              The configuration index of to name.
     2627 * @param   fNamespaces         The namespaces to apply the path to
     2628 *                              (RTFSISOMAKER_NAMESPACE_XXX).
     2629 * @param   pszRockName         The rock ridge name.  Passing NULL will restore
     2630 *                              it back to the specified name, while an empty
     2631 *                              string will restore it to the namespace name.
     2632 */
     2633RTDECL(int) RTFsIsoMakerObjSetRockName(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszRockName)
     2634{
     2635    /*
     2636     * Validate and translate input.
     2637     */
     2638    PRTFSISOMAKERINT pThis = hIsoMaker;
     2639    RTFSISOMAKER_ASSERT_VALID_HANDLE_RET(pThis);
     2640    AssertReturn(!(fNamespaces & ~RTFSISOMAKER_NAMESPACE_VALID_MASK), VERR_INVALID_FLAGS);
     2641    size_t cchRockName;
     2642    if (pszRockName)
     2643    {
     2644        AssertPtrReturn(pszRockName, VERR_INVALID_POINTER);
     2645        cchRockName = strlen(pszRockName);
     2646        AssertReturn(cchRockName < _1K, VERR_FILENAME_TOO_LONG);
     2647        AssertReturn(memchr(pszRockName, '/', cchRockName) == NULL, VERR_INVALID_NAME);
     2648    }
     2649    else
     2650        cchRockName = 0;
     2651    PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj);
     2652    AssertReturn(pObj, VERR_OUT_OF_RANGE);
     2653    AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER);
     2654
     2655    /*
     2656     * Execute requested actions.
     2657     */
     2658    for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++)
     2659        if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace)
     2660        {
     2661            PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace);
     2662            if (   pNamespace->uLevel > 0
     2663                && pNamespace->uRockRidgeLevel > 0)
     2664            {
     2665                PRTFSISOMAKERNAME pName = *rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace);
     2666                if (pName)
     2667                {
     2668                    /* Free the old rock ridge name. */
     2669                    if (pName->fRockRidgeNmAlloced)
     2670                    {
     2671                        RTMemFree(pName->pszRockRidgeNm);
     2672                        pName->pszRockRidgeNm      = NULL;
     2673                        pName->fRockRidgeNmAlloced = false;
     2674                    }
     2675
     2676                    /* Set new rock ridge name. */
     2677                    if (cchRockName > 0)
     2678                    {
     2679                        pName->pszRockRidgeNm = (char *)RTMemDup(pszRockName, cchRockName + 1);
     2680                        if (!pName->pszRockRidgeNm)
     2681                        {
     2682                            pName->pszRockRidgeNm = (char *)pName->pszSpecNm;
     2683                            pName->cchRockRidgeNm = pName->cchSpecNm;
     2684                            return VERR_NO_MEMORY;
     2685                        }
     2686                        pName->cchRockRidgeNm = (uint16_t)cchRockName;
     2687                        pName->fRockRidgeNmAlloced = true;
     2688                    }
     2689                    else if (pszRockName == NULL)
     2690                    {
     2691                        pName->pszRockRidgeNm = (char *)pName->pszSpecNm;
     2692                        pName->cchRockRidgeNm = pName->cchSpecNm;
     2693                    }
     2694                    else
     2695                    {
     2696                        pName->pszRockRidgeNm = pName->szName;
     2697                        pName->cchRockRidgeNm = pName->cchName;
     2698                    }
     2699                }
     2700            }
     2701        }
     2702    return VINF_SUCCESS;
     2703
     2704}
     2705
     2706
     2707/**
    26192708 * Enables or disable syslinux boot info table patching of a file.
    26202709 *
     
    27542843 * @returns IPRT status code.
    27552844 * @param   pThis               The ISO make instance.
     2845 * @param   pObjInfo            Pointer to object attributes, must be set to
     2846 *                              UNIX.  The size and hardlink counts are ignored.
     2847 *                              Optional.
    27562848 * @param   ppDir               Where to return the directory.
    27572849 */
    2758 static int rtFsIsoMakerAddUnnamedDirWorker(PRTFSISOMAKERINT pThis, PRTFSISOMAKERDIR *ppDir)
     2850static int rtFsIsoMakerAddUnnamedDirWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, PRTFSISOMAKERDIR *ppDir)
    27592851{
    27602852    PRTFSISOMAKERDIR pDir = (PRTFSISOMAKERDIR)RTMemAllocZ(sizeof(*pDir));
    27612853    AssertReturn(pDir, VERR_NO_MEMORY);
    2762     int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR, NULL);
     2854    int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR, pObjInfo);
    27632855    if (RT_SUCCESS(rc))
    27642856    {
     
    27792871 * @returns IPRT status code
    27802872 * @param   hIsoMaker           The ISO maker handle.
     2873 * @param   pObjInfo            Pointer to object attributes, must be set to
     2874 *                              UNIX.  The size and hardlink counts are ignored.
     2875 *                              Optional.
    27812876 * @param   pidxObj             Where to return the configuration index of the
    27822877 *                              directory.
    27832878 * @sa      RTFsIsoMakerAddDir, RTFsIsoMakerObjSetPath
    27842879 */
    2785 RTDECL(int) RTFsIsoMakerAddUnnamedDir(RTFSISOMAKER hIsoMaker, uint32_t *pidxObj)
     2880RTDECL(int) RTFsIsoMakerAddUnnamedDir(RTFSISOMAKER hIsoMaker, PCRTFSOBJINFO pObjInfo, uint32_t *pidxObj)
    27862881{
    27872882    PRTFSISOMAKERINT pThis = hIsoMaker;
    27882883    RTFSISOMAKER_ASSERT_VALID_HANDLE_RET(pThis);
    27892884    AssertPtrReturn(pidxObj, VERR_INVALID_POINTER);
     2885    if (pObjInfo)
     2886    {
     2887        AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER);
     2888        AssertReturn(pObjInfo->Attr.enmAdditional == RTFSOBJATTRADD_UNIX, VERR_INVALID_PARAMETER);
     2889        AssertReturn(RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode), VERR_INVALID_FLAGS);
     2890    }
    27902891    AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER);
    27912892
    27922893    PRTFSISOMAKERDIR pDir;
    2793     int rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pDir);
     2894    int rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, pObjInfo, &pDir);
    27942895    *pidxObj = RT_SUCCESS(rc) ? pDir->Core.idxObj : UINT32_MAX;
    27952896    return rc;
     
    28162917
    28172918    uint32_t idxObj;
    2818     int rc = RTFsIsoMakerAddUnnamedDir(hIsoMaker, &idxObj);
     2919    int rc = RTFsIsoMakerAddUnnamedDir(hIsoMaker, NULL /*pObjInfo*/, &idxObj);
    28192920    if (RT_SUCCESS(rc))
    28202921    {
  • trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp

    r67791 r67794  
    370370 * @param   pThis       The importer instance.
    371371 * @param   pDirRec     The directory record.
     372 * @param   pObjInfo    Object information.
    372373 * @param   cbData      The actual directory data size.  (Always same as in the
    373374 *                      directory record, but this what we do for files below.)
     
    375376 * @param   idxParent   Parent directory.
    376377 * @param   pszName     The name.
     378 * @param   pszRockName The rock ridge name.
    377379 * @param   cDepth      The depth to add it with.
    378380 * @param   pTodoList   The todo list (for directories).
    379381 */
    380 static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec, uint64_t cbData,
     382static int rtFsIsoImportProcessIso9660AddAndNameDirectory(PRTFSISOMKIMPORTER pThis, PCISO9660DIRREC pDirRec,
     383                                                          PCRTFSOBJINFO pObjInfo, uint64_t cbData,
    381384                                                          uint32_t fNamespace, uint32_t idxParent, const char *pszName,
    382                                                           uint8_t cDepth, PRTLISTANCHOR pTodoList)
     385                                                          const char *pszRockName, uint8_t cDepth, PRTLISTANCHOR pTodoList)
    383386{
    384387    Assert(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY);
    385388    uint32_t idxObj;
    386     int rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, &idxObj);
     389    int rc = RTFsIsoMakerAddUnnamedDir(pThis->hIsoMaker, pObjInfo, &idxObj);
    387390    if (RT_SUCCESS(rc))
    388391    {
     
    398401            pThis->pResults->cAddedNames++;
    399402
    400             /*
    401              * Push it onto the traversal stack.
    402              */
    403             PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir));
    404             if (pImpDir)
     403            if (*pszRockName != '\0' && strcmp(pszName, pszRockName))
     404                rc = RTFsIsoMakerObjSetRockName(pThis->hIsoMaker, idxObj, fNamespace, pszRockName);
     405            if (RT_SUCCESS(rc))
    405406            {
    406                 Assert((uint32_t)cbData == cbData /* no multi-extents for dirs makes it this far */);
    407                 pImpDir->cbDir       = (uint32_t)cbData;
    408                 pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
    409                 pImpDir->idxObj      = idxObj;
    410                 pImpDir->cDepth      = cDepth;
    411                 RTListAppend(pTodoList, &pImpDir->Entry);
     407                /*
     408                 * Push it onto the traversal stack.
     409                 */
     410                PRTFSISOMKIMPDIR pImpDir = (PRTFSISOMKIMPDIR)RTMemAlloc(sizeof(*pImpDir));
     411                if (pImpDir)
     412                {
     413                    Assert((uint32_t)cbData == cbData /* no multi-extents for dirs makes it this far */);
     414                    pImpDir->cbDir       = (uint32_t)cbData;
     415                    pImpDir->offDirBlock = ISO9660_GET_ENDIAN(&pDirRec->offExtent);
     416                    pImpDir->idxObj      = idxObj;
     417                    pImpDir->cDepth      = cDepth;
     418                    RTListAppend(pTodoList, &pImpDir->Entry);
     419                }
     420                else
     421                    rc = rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR");
    412422            }
    413423            else
    414                 rc = rtFsIsoImpError(pThis, VERR_NO_MEMORY, "Could not allocate RTFSISOMKIMPDIR");
     424                rc = rtFsIsoImpError(pThis, rc, "Error setting rock ridge name for directory '%s' to '%s'", pszName, pszRockName);
    415425        }
    416426        else
     
    812822                    LogRel(("rtFsIsoImport/Rock: Malformed 'SL' entry: cbEntry=%#x (vs %#x), bVersion=%#x (vs %#x) fFlags=%#x comp[0].fFlags=%#x\n",
    813823                            pUnion->SL.Hdr.cbEntry, RT_OFFSETOF(ISO9660RRIPSL, abComponents[2]),
    814                             pUnion->SL.Hdr.bVersion, ISO9660RRIPSL_VER, RT_BE2H_U32(pUnion->SL.fFlags), pUnion->SL.abComponents[0]));
     824                            pUnion->SL.Hdr.bVersion, ISO9660RRIPSL_VER, pUnion->SL.fFlags, pUnion->SL.abComponents[0]));
    815825                else if (pThis->fSeenLastSL)
    816                     LogRel(("rtFsIsoImport/Rock: Unexpected 'SL' entry\n"));
     826                    LogRel(("rtFsIsoImport/Rock: Unexpected 'SL!' entry\n"));
    817827                else
    818828                {
     
    902912                            }
    903913                        }
    904                     } while (cbSrcLeft >= 2);
     914                    }
    905915                    pThis->szRockSymlinkTargetBuf[offDst] = '\0';
     916
     917                    /* Purge the encoding as we don't want invalid UTF-8 floating around. */
     918                    RTStrPurgeEncoding(pThis->szRockSymlinkTargetBuf);
    906919                }
    907920                break;
    908921
    909922            case MAKE_SIG(ISO9660RRIPNM_SIG1, ISO9660RRIPNM_SIG2): /* NM */
     923                if (   pUnion->NM.Hdr.bVersion != ISO9660RRIPNM_VER
     924                    || pUnion->NM.Hdr.cbEntry < RT_OFFSETOF(ISO9660RRIPNM, achName)
     925                    || (pUnion->NM.fFlags & ISO9660RRIP_NM_F_RESERVED_MASK) )
     926                    LogRel(("rtFsIsoImport/Rock: Malformed 'NM' entry: cbEntry=%#x (vs %#x), bVersion=%#x (vs %#x) fFlags=%#x %.*Rhxs\n",
     927                            pUnion->NM.Hdr.cbEntry, RT_OFFSETOF(ISO9660RRIPNM, achName),
     928                            pUnion->NM.Hdr.bVersion, ISO9660RRIPNM_VER, pUnion->NM.fFlags,
     929                            pUnion->NM.Hdr.cbEntry - RT_MIN(pUnion->NM.Hdr.cbEntry, RT_OFFSETOF(ISO9660RRIPNM, achName)),
     930                            &pUnion->NM.achName[0] ));
     931                else if (pThis->fSeenLastNM)
     932                    LogRel(("rtFsIsoImport/Rock: Unexpected 'NM' entry!\n"));
     933                else
     934                {
     935                    pThis->fSeenLastNM = !(pUnion->NM.fFlags & ISO9660RRIP_NM_F_CONTINUE);
     936
     937                    uint8_t const cchName = pUnion->NM.Hdr.cbEntry - (uint8_t)RT_OFFSETOF(ISO9660RRIPNM, achName);
     938                    if (pUnion->NM.fFlags & (ISO9660RRIP_NM_F_CURRENT | ISO9660RRIP_NM_F_PARENT))
     939                    {
     940                        if (cchName == 0 && pThis->szRockNameBuf[0] == '\0')
     941                            Log(("rtFsIsoImport/Rock: Ignoring 'NM' entry for '.' and '..'\n"));
     942                        else
     943                            LogRel(("rtFsIsoImport/Rock: Ignoring malformed 'NM' using '.' or '..': fFlags=%#x cchName=%#x %.*Rhxs; szRockNameBuf='%s'\n",
     944                                    pUnion->NM.fFlags, cchName, cchName, pUnion->NM.achName, pThis->szRockNameBuf));
     945                        pThis->szRockNameBuf[0] = '\0';
     946                        pThis->fSeenLastNM = true;
     947                    }
     948                    else
     949                    {
     950                        size_t offDst = strlen(pThis->szRockNameBuf);
     951                        if (offDst + cchName < sizeof(pThis->szRockNameBuf))
     952                        {
     953                            memcpy(&pThis->szRockNameBuf[offDst], pUnion->NM.achName, cchName);
     954                            pThis->szRockNameBuf[offDst + cchName] = '\0';
     955
     956                            /* Purge the encoding as we don't want invalid UTF-8 floating around. */
     957                            RTStrPurgeEncoding(pThis->szRockSymlinkTargetBuf);
     958                        }
     959                        else
     960                        {
     961                            LogRel(("rtFsIsoImport/Rock: 'NM' constructs a too long name, ignoring it all: '%s%.*s'\n",
     962                                    pThis->szRockNameBuf, cchName, pUnion->NM.achName));
     963                            pThis->szRockNameBuf[0] = '\0';
     964                            pThis->fSeenLastNM = true;
     965                        }
     966                    }
     967                }
    910968                break;
    911969
     
    12771335
    12781336            pThis->szRockNameBuf[0] = '\0';
     1337            pThis->szRockSymlinkTargetBuf[0] = '\0';
    12791338            if (cbSys > 0 && !(pThis->fFlags & RTFSISOMK_IMPORT_F_NO_ROCK_RIDGE))
    12801339            {
     
    13831442                 */
    13841443                if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY)
    1385                     rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, cbData, fNamespace, idxDir,
    1386                                                                    pThis->szNameBuf, cDepth + 1, pTodoList);
     1444                    rtFsIsoImportProcessIso9660AddAndNameDirectory(pThis, pDirRec, &ObjInfo, cbData, fNamespace, idxDir,
     1445                                                                   pThis->szNameBuf, pThis->szRockNameBuf, cDepth + 1, pTodoList);
    13871446                else
    13881447                    rtFsIsoImportProcessIso9660AddAndNameFile(pThis, pDirRec, cbData, fNamespace, idxDir, pThis->szNameBuf);
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