VirtualBox

Changeset 67303 in vbox for trunk/src/VBox/Runtime/common/fs


Ignore:
Timestamp:
Jun 8, 2017 2:54:31 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116007
Message:

IPRT: More ISO maker code.

File:
1 edited

Legend:

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

    r67281 r67303  
    172172    bool                    fTransNmAlloced : 1;
    173173
    174 /** @todo more rock ridge info here.    */
     174    /** The mode mask.
     175     * Starts out as a copy of RTFSISOMAKEROBJ::fMode. */
     176    RTFMODE                 fMode;
     177    /** The owner ID.
     178     * Starts out as a copy of RTFSISOMAKEROBJ::uid. */
     179    RTUID                   uid;
     180    /** The group ID.
     181     * Starts out as a copy of RTFSISOMAKEROBJ::gid. */
     182    RTGID                   gid;
     183    /** The device number if a character or block device.
     184     * This is for Rock Ridge.  */
     185    RTDEV                   Device;
     186    /** The number of hardlinks to report in the file stats.
     187     * This is for Rock Ridge.  */
     188    uint32_t                cHardlinks;
     189    /** The inode/serial number.
     190     * This is for Rock Ridge.  */
     191    uint64_t                INode;
    175192
    176193    /** The name length. */
     
    186203{
    187204    /** The namespace root. */
    188     RTFSISOMAKERNAME        pRoot;
     205    PRTFSISOMAKERNAME       pRoot;
    189206    /** Total number of name nodes in the namespace. */
    190207    uint32_t                cNames;
     
    193210    /** The namespace selector (RTFSISOMAKER_NAMESPACE_XXX). */
    194211    uint32_t                fNamespace;
     212    /** Offset into RTFSISOMAKERNAMESPACE of the name member. */
     213    uint32_t                offName;
    195214    /** The configuration level for this name space.
    196215     *     - For UDF and HFS namespaces this is either @c true or @c false.
     
    202221    uint8_t                 uRockRidgeLevel;
    203222    /** Set if TRANS.TBL files are to be generated for this namespace. */
     223    bool                    fTransTbl;
    204224} RTFSISOMAKERNAMESPACE;
    205225/** Pointer to a namespace. */
    206226typedef RTFSISOMAKERNAMESPACE *PRTFSISOMAKERNAMESPACE;
     227/** Pointer to a const namespace. */
     228typedef RTFSISOMAKERNAMESPACE const *PCRTFSISOMAKERNAMESPACE;
    207229
    208230
    209231/**
    210232 * Common base structure for the file system objects.
     233 *
     234 * The times are shared across all namespaces, while the uid, gid and mode are
     235 * duplicates in each namespace.
    211236 */
    212237typedef struct RTFSISOMAKEROBJ
     
    228253    PRTFSISOMAKERNAME       pHfsName;
    229254
     255    /** Birth (creation) time. */
     256    RTTIMESPEC              BirthTime;
     257    /** Attribute change time. */
     258    RTTIMESPEC              ChangeTime;
     259    /** Modification time. */
     260    RTTIMESPEC              ModificationTime;
     261    /** Accessed time. */
     262    RTTIMESPEC              AccessedTime;
     263
     264    /** Owner ID. */
     265    RTUID                   uid;
     266    /** Group ID. */
     267    RTGID                   gid;
     268    /** Attributes (unix permissions bits mainly). */
     269    RTFMODE                 fMode;
     270
    230271} RTFSISOMAKEROBJ;
    231272
     
    238279    RTFSISOMAKERSRCTYPE_INVALID = 0,
    239280    RTFSISOMAKERSRCTYPE_PATH,
    240     RTFSISOMAKERSRCTYPE_VFS_IO_STREAM,
     281    RTFSISOMAKERSRCTYPE_VFS_FILE,
    241282    RTFSISOMAKERSRCTYPE_END
    242283} RTFSISOMAKERSRCTYPE;
     
    259300    union
    260301    {
    261         /** Path to the source file. */
     302        /** Path to the source file.
     303         * Allocated together with this structure.  */
    262304        const char         *pszSrcPath;
    263         /** Source I/O stream (or file). */
    264         RTVFSIOSTREAM       hVfsIoStr;
     305        /** Source VFS file. */
     306        RTVFSFILE           hVfsFile;
    265307    } u;
    266308} RTFSISOMAKERFILE;
     
    293335    uint32_t volatile       cRefs;
    294336
    295     /** @name Name space configuration.
    296      * @{ */
    297337    /** Set after we've been fed the first bit of content.
    298338     * This means that the namespace configuration has been finalized and can no
     
    300340     * after having started to add files. */
    301341    bool                    fSeenContent;
    302     /** The ISO level (1-3), default is 3.
    303      * @todo support mkisofs level 4 (ISO-9660:1990, version 2). */
    304     uint8_t                 uIsoLevel;
    305     /** The joliet UCS level (1, 2, or 3), 0 if joliet is not enabled. */
    306     uint8_t                 uJolietLevel;
    307     /** Enables UDF.
    308      * @remarks not yet implemented. */
    309     bool                    fUdf;
    310     /** Enables HFS
    311      * @remarks not yet implemented. */
    312     bool                    fHfs;
    313     /** @} */
    314342
    315343    /** The primary ISO-9660 namespace. */
     
    334362    uint64_t                cbTotal;
    335363
     364    /** The 'now' timestamp we use for the whole image.
     365     * This way we'll save lots of RTTimeNow calls and have similar timestamps
     366     * over the whole image. */
     367    RTTIMESPEC              ImageCreationTime;
     368    /** The default owner ID. */
     369    RTUID                   uidDefault;
     370    /** The default group ID. */
     371    RTGID                   gidDefault;
     372    /** The default file mode mask. */
     373    RTFMODE                 fDefaultFileMode;
     374    /** The default file mode mask. */
     375    RTFMODE                 fDefaultDirMode;
     376
    336377} RTFSISOMAKERINT;
    337378/** Pointer to an ISO maker instance. */
     
    349390    /** The RTFSISOMAKERNAMESPACE_XXX indicator.  */
    350391    uint32_t        fNamespace;
    351     /** Offset into RTFSISOMAKERINT of the root member. */
    352     uintptr_t       offRoot;
     392    /** Offset into RTFSISOMAKERINT of the namespace member. */
     393    uintptr_t       offNamespace;
    353394    /** Offset into RTFSISOMAKERNAMESPACE of the name member. */
    354395    uintptr_t       offName;
     
    357398} g_aRTFsIsoNamespaces[] =
    358399{
    359     {   RTFSISOMAKERNAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, pPrimaryIsoRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" },
    360     {   RTFSISOMAKERNAMESPACE_JOLIET,   RT_OFFSETOF(RTFSISOMAKERINT, pJolietRoot),     RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName),  "joliet" },
    361     {   RTFSISOMAKERNAMESPACE_UDF,      RT_OFFSETOF(RTFSISOMAKERINT, pUdfRoot),        RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName),     "udf" },
    362     {   RTFSISOMAKERNAMESPACE_HFS,      RT_OFFSETOF(RTFSISOMAKERINT, pHfsRoot),        RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName),     "hfs" },
     400    {   RTFSISOMAKERNAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, PrimaryIso), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" },
     401    {   RTFSISOMAKERNAMESPACE_JOLIET,   RT_OFFSETOF(RTFSISOMAKERINT, Joliet),     RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName),  "joliet" },
     402    {   RTFSISOMAKERNAMESPACE_UDF,      RT_OFFSETOF(RTFSISOMAKERINT, Udf),        RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName),     "udf" },
     403    {   RTFSISOMAKERNAMESPACE_HFS,      RT_OFFSETOF(RTFSISOMAKERINT, Hfs),        RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName),     "hfs" },
    363404};
    364405
     
    443484
    444485        pThis->PrimaryIso.fNamespace        = RTFSISOMAKERNAMESPACE_ISO_9660;
     486        pThis->PrimaryIso.offName           = RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName);
    445487        pThis->PrimaryIso.uLevel            = 3; /* 30 char names, large files */
    446488        pThis->PrimaryIso.uRockRidgeLevel   = 1;
     489        pThis->PrimaryIso.fTransTbl         = true;
    447490        pThis->Joliet.fNamespace            = RTFSISOMAKERNAMESPACE_JOLIET;
     491        pThis->Joliet.offName               = RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName);
    448492        pThis->Joliet.uLevel                = 3;
    449493        //pThis->Joliet.uRockRidgeLevel     = 0;
     494        //pThis->Joliet.fTransTbl           = false;
    450495        pThis->Udf.fNamespace               = RTFSISOMAKERNAMESPACE_UDF;
     496        pThis->Udf.offName                  = RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName);
    451497        //pThis->Udf.uLevel                 = 0;
    452498        //pThis->Udf.uRockRidgeLevel        = 0;
     499        //pThis->Udf.fTransTbl              = false;
    453500        pThis->Hfs.fNamespace               = RTFSISOMAKERNAMESPACE_HFS;
     501        pThis->Hfs.offName                  = RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName);
    454502        //pThis->Hfs.uLevel                 = 0;
    455503        //pThis->Hfs.uRockRidgeLevel        = 0;
     504        //pThis->Hfs.fTransTbl              = false;
    456505
    457506        RTListInit(&pThis->ObjectHead);
    458507        //pThis->cObjects                   = 0;
    459         //pThis->cNames                     = 0;
    460508        //pThis->cbData                     = 0;
     509
    461510        pThis->cbTotal                      = _32K /* The system area size. */
    462511                                            + RTFSISOMAKER_SECTOR_SIZE /* Primary volume descriptor. */
    463512                                            + RTFSISOMAKER_SECTOR_SIZE /* Secondary volume descriptor for joliet. */
    464513                                            + RTFSISOMAKER_SECTOR_SIZE /* Terminator descriptor. */;
     514
     515        //pThis->uidDefault                 = 0;
     516        //pThis->gidDefault                 = 0;
     517        pThis->fDefaultFileMode             = 0444 | RTFS_TYPE_FILE      | RTFS_DOS_ARCHIVED  | RTFS_DOS_READONLY;
     518        pThis->fDefaultDirMode              = 0555 | RTFS_TYPE_DIRECTORY | RTFS_DOS_DIRECTORY | RTFS_DOS_READONLY;
     519
     520        RTTimeNow(&pThis->ImageCreationTime);
     521
    465522        *phIsoMaker = pThis;
    466523        return VINF_SUCCESS;
    467524    }
    468525    return VERR_NO_MEMORY;
     526}
     527
     528
     529/**
     530 * Frees an object.
     531 *
     532 * This is a worker for rtFsIsoMakerDestroy and RTFsIsoMakerObjRemove.
     533 *
     534 * @param   pObj                The object to free.
     535 */
     536DECLINLINE(void) rtFsIsoMakerObjDestroy(PRTFSISOMAKEROBJ pObj)
     537{
     538    if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE)
     539    {
     540        PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj;
     541        switch (pFile->enmSrcType)
     542        {
     543            case RTFSISOMAKERSRCTYPE_PATH:
     544                /* do nothing. */
     545                break;
     546
     547            case RTFSISOMAKERSRCTYPE_VFS_FILE:
     548                RTVfsFileRelease(pFile->u.hVfsFile);
     549                pFile->u.hVfsFile = NIL_RTVFSFILE;
     550                break;
     551
     552            case RTFSISOMAKERSRCTYPE_INVALID:
     553            case RTFSISOMAKERSRCTYPE_END:
     554                AssertFailed();
     555                break;
     556
     557            /* no default, want warnings */
     558        }
     559    }
     560
     561    RTMemFree(pObj);
     562}
     563
     564
     565/**
     566 * Frees a namespace node.
     567 *
     568 * This is a worker for rtFsIsoMakerDestroyTree and rtFsIsoMakerObjUnsetName.
     569 *
     570 * @param   pName               The node to free.
     571 */
     572DECLINLINE(void) rtFsIsoMakerDestroyName(PRTFSISOMAKERNAME pName)
     573{
     574    if (pName->fRockRidgeNmAlloced)
     575    {
     576        RTMemFree(pName->pszRockRidgeNm);
     577        pName->pszRockRidgeNm = NULL;
     578    }
     579    if (pName->fTransNmAlloced)
     580    {
     581        RTMemFree(pName->pszTransNm);
     582        pName->pszTransNm = NULL;
     583    }
     584    RTMemFree(pName);
    469585}
    470586
     
    486602        else
    487603        {
    488             RTMemFree(pCur->pszRockRidgeNm);
    489             pCur->pszRockRidgeNm = NULL;
    490             RTMemFree(pCur->pszTransNm);
    491             pCur->pszTransNm = NULL;
    492604            PRTFSISOMAKERNAME pNext = pCur->pParent;
    493             RTMemFree(pCur);
     605            rtFsIsoMakerDestroyName(pCur);
    494606
    495607            /* Unlink from parent, we're the last entry. */
     
    519631static void rtFsIsoMakerDestroy(PRTFSISOMAKERINT pThis)
    520632{
    521     rtFsIsoMakerDestroyTree(pThis->pPrimaryIsoRoot);
    522     rtFsIsoMakerDestroyTree(pThis->pJolietRoot);
    523     rtFsIsoMakerDestroyTree(pThis->pUdfRoot);
    524     rtFsIsoMakerDestroyTree(pThis->pHfsRoot);
     633    rtFsIsoMakerDestroyTree(pThis->PrimaryIso.pRoot);
     634    rtFsIsoMakerDestroyTree(pThis->Joliet.pRoot);
     635    rtFsIsoMakerDestroyTree(pThis->Udf.pRoot);
     636    rtFsIsoMakerDestroyTree(pThis->Hfs.pRoot);
    525637
    526638    PRTFSISOMAKEROBJ pCur;
     
    529641    {
    530642        RTListNodeRemove(&pCur->Entry);
    531         RTMemFree(pCur);
     643        rtFsIsoMakerObjDestroy(pCur);
    532644    }
    533645}
     
    592704    AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
    593705
    594     pThis->uIsoLevel = uIsoLevel;
     706    pThis->PrimaryIso.uLevel = uIsoLevel;
    595707    return VINF_SUCCESS;
    596708}
     
    612724    AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
    613725
    614     if (pThis->uJolietLevel != uJolietLevel)
     726    if (pThis->Joliet.uLevel != uJolietLevel)
    615727    {
    616728        if (uJolietLevel == 0)
    617729            pThis->cbTotal -= RTFSISOMAKER_SECTOR_SIZE;
    618         else if (pThis->uJolietLevel == 0)
     730        else if (pThis->Joliet.uLevel == 0)
    619731            pThis->cbTotal += RTFSISOMAKER_SECTOR_SIZE;
    620         pThis->uJolietLevel = uJolietLevel;
     732        pThis->Joliet.uLevel = uJolietLevel;
    621733    }
    622734    return VINF_SUCCESS;
     
    639751    AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER);
    640752
    641     pThis->uRockRidgeLevel = uLevel;
     753    pThis->PrimaryIso.uRockRidgeLevel = uLevel;
    642754    return VINF_SUCCESS;
    643755}
     
    659771    AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER);
    660772
    661     pThis->uJolietRockRidgeLevel = uLevel;
     773    pThis->Joliet.uRockRidgeLevel = uLevel;
    662774    return VINF_SUCCESS;
    663775}
     
    673785 */
    674786
    675 
     787#if 0
    676788/**
    677789 * Gets the pointer to the root member for the given namespace.
     
    688800    return (PPRTFSISOMAKERNAME)((uintptr_t)pThis + g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[fNamespace]].offRoot);
    689801}
     802#endif
    690803
    691804
     
    695808 * @returns Pointer to name member.
    696809 * @param   pObj                The object to find a name member in.
    697  * @param   fNamespace          The namespace which name to find.
    698  */
    699 static PPRTFSISOMAKERNAME rtFsIsoMakerObjGetNameForNamespace(PRTFSISOMAKEROBJ pObj, uint32_t fNamespace)
    700 {
    701     Assert(RT_IS_POWER_OF_TWO(fNamespace));
    702     Assert(fNamespace);
    703     Assert(fNamespace <= RTFSISOMAKERNAMESPACE_HFS);
    704     return (PPRTFSISOMAKERNAME)((uintptr_t)pObj + g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[fNamespace]].offName);
     810 * @param   pNamespace          The namespace which name to calculate.
     811 */
     812DECLINLINE(PPRTFSISOMAKERNAME) rtFsIsoMakerObjGetNameForNamespace(PRTFSISOMAKEROBJ pObj, PCRTFSISOMAKERNAMESPACE pNamespace)
     813{
     814    return (PPRTFSISOMAKERNAME)((uintptr_t)pObj + pNamespace->offName);
    705815}
    706816
     
    875985     * Produce a first name.
    876986     */
     987    uint8_t const uIsoLevel = pThis->PrimaryIso.uLevel;
    877988    size_t cchDst;
    878989    size_t offDstDot;
    879990    if (fIsDir)
    880         offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,
     991        offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,
    881992                                                         pchSrc, cchSrc);
    882993    else
     
    8891000
    8901001        if (offLastDot == cchSrc)
    891             offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,
     1002            offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,
    8921003                                                             pchSrc, cchSrc);
    8931004        else
     
    8951006            const char * const pchSrcExt = &pchSrc[offLastDot + 1];
    8961007            size_t       const cchSrcExt = cchSrc - offLastDot - 1;
    897             if (pThis->uIsoLevel < 2)
     1008            if (uIsoLevel < 2)
    8981009            {
    8991010                cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, 8, pchSrc, cchSrc);
     
    9361047     * Mangle the name till we've got a unique one.
    9371048     */
    938     size_t const cchMaxBasename = (pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8) - (cchDst - offDstDot);
     1049    size_t const cchMaxBasename = (uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8) - (cchDst - offDstDot);
    9391050    size_t       cchInserted = 0;
    9401051    for (uint32_t i = 0; i < _32K; i++)
     
    9751086 * @returns IPRT status code.
    9761087 * @param   pThis       The ISO maker instance.
     1088 * @param   pNamespace  The namespace which rules to normalize it according to.
    9771089 * @param   pParent     The parent directory.  NULL if root.
    9781090 * @param   pchSrc      The specified name to normalize (not necessarily zero
    9791091 *                      terminated).
    9801092 * @param   cchSrc      The length of the specified name.
    981  * @param   fNamespace  The namespace rules to normalize it according to.
    9821093 * @param   fIsDir      Indicates whether it's a directory or file (like).
    9831094 * @param   pszDst      The output buffer.  Must be at least 32 bytes.
     
    9861097 *                      not counting the terminator).
    9871098 */
    988 static int rtFsIsoMakerNormalizeNameForNamespace(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAME pParent,
    989                                                  const char *pchSrc, size_t cchSrc, uint32_t fNamespace, bool fIsDir,
     1099static int rtFsIsoMakerNormalizeNameForNamespace(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace,
     1100                                                 PRTFSISOMAKERNAME pParent, const char *pchSrc, size_t cchSrc, bool fIsDir,
    9901101                                                 char *pszDst, size_t cbDst, size_t *pcchDst)
    9911102{
     
    9961107         */
    9971108        AssertReturn(!rtFsIsoMakerFindEntryInDirBySpec(pParent, pchSrc, cchSrc), VERR_ALREADY_EXISTS);
    998         switch (fNamespace)
     1109        switch (pNamespace->fNamespace)
    9991110        {
    10001111            /*
     
    10091120            case RTFSISOMAKERNAMESPACE_JOLIET:
    10101121            {
    1011 /** @todo Joliet name limit.   */
     1122/** @todo Joliet name limit and check for duplicates.   */
    10121123                AssertReturn(cbDst > cchSrc, VERR_BUFFER_OVERFLOW);
    10131124                memcpy(pszDst, pchSrc, cchSrc);
     
    10471158 * @param   pNamespace  The namespace.
    10481159 * @param   pObj        The object to name.
    1049  * @param   ppName      The pointer to the object's namespace member.
    10501160 * @param   pParent     The parent namespace entry
    10511161 * @param   pchSpec     The specified name (not necessarily terminated).
     
    10541164 */
    10551165static int rtFsIsoMakerObjSetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj,
    1056                                   PPRTFSISOMAKERNAME ppName, PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec,
    1057                                   PPRTFSISOMAKERNAME ppNewName)
     1166                                  PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec, PPRTFSISOMAKERNAME ppNewName)
    10581167{
    10591168    Assert(cchSpec < _32K);
     
    10631172     * large enough.  If root object, make sure we haven't got a root already.
    10641173     */
    1065     PPRTFSISOMAKERNAME ppRoot;
    10661174    if (pParent)
    10671175    {
     
    10771185            pParent->pDir->papChildren = (PPRTFSISOMAKERNAME)pvNew;
    10781186        }
    1079         ppRoot = NULL;
    10801187    }
    10811188    else
    1082     {
    1083         ppRoot = rtFsIsoMakerGetRootForNamespace(pThis, fNamespace);
    1084         AssertReturn(*ppRoot, VERR_INTERNAL_ERROR_5);
    1085     }
     1189        AssertReturn(pNamespace->pRoot == NULL, VERR_INTERNAL_ERROR_5);
    10861190
    10871191    /*
     
    10901194    size_t cchName;
    10911195    char   szName[RTFSISOMAKER_MAX_NAME_BUF];
    1092     int rc = rtFsIsoMakerNormalizeNameForNamespace(pThis, pParent, pchSpec, cchSpec, fNamespace,
     1196    int rc = rtFsIsoMakerNormalizeNameForNamespace(pThis, pNamespace, pParent, pchSpec, cchSpec,
    10931197                                                   pObj->enmType == RTFSISOMAKEROBJTYPE_DIR,
    10941198                                                   szName, sizeof(szName), &cchName);
     
    11191223            pName->fRockRidgeNmAlloced  = false;
    11201224            pName->fTransNmAlloced      = false;
     1225
     1226            pName->fMode                = pObj->fMode;
     1227            pName->uid                  = pObj->uid;
     1228            pName->gid                  = pObj->gid;
     1229            pName->Device               = 0;
     1230            pName->cHardlinks           = 1;
     1231            pName->INode                = pObj->idxObj;
    11211232
    11221233            memcpy(pName->szName, szName, cchName);
     
    11461257                pParent->pDir->papChildren[pParent->pDir->cChildren++] = pName;
    11471258            else
    1148                 *ppRoot = pName;
    1149             *ppName = pName;
    1150             pThis->cNames++;
     1259                pNamespace->pRoot = pName;
     1260            *rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace) = pName;
     1261            pNamespace->cNames++;
    11511262
    11521263            /*
     
    11621273
    11631274
    1164 static int rtFsIsoMakerPathToParent(PRTFSISOMAKERINT pThis, PPRTFSISOMAKERNAME ppRoot, uint32_t fNamespace, const char *pszPath,
     1275static int rtFsIsoMakerPathToParent(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, const char *pszPath,
    11651276                                    PPRTFSISOMAKERNAME ppParent, const char **ppszEntry, size_t *pcchEntry)
    11661277{
     
    11751286    AssertReturn(*pszPath, VERR_INTERNAL_ERROR_4);
    11761287
    1177     PRTFSISOMAKERNAME pParent = *ppRoot;
     1288    PRTFSISOMAKERNAME pParent = pNamespace->pRoot;
    11781289    if (!pParent)
    11791290    {
     
    11911302            Assert(pDir->Core.idxObj == 0);
    11921303            Assert(pDir->Core.enmType == RTFSISOMAKEROBJTYPE_DIR);
    1193             Assert(*rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, fNamespace) == NULL);
     1304            Assert(*rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, pNamespace) == NULL);
    11941305#endif
    11951306        }
    11961307
    1197         rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pDir->Core, rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, fNamespace),
    1198                                     NULL /*pParent*/, "", 0, &pParent);
     1308        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pDir->Core, NULL /*pParent*/, "", 0, &pParent);
    11991309        AssertRCReturn(rc, rc);
    1200         AssertReturn(*ppRoot, VERR_INTERNAL_ERROR_4);
    1201         pParent = *ppRoot;
     1310        pParent = pNamespace->pRoot;
     1311        AssertReturn(pParent, VERR_INTERNAL_ERROR_4);
    12021312    }
    12031313
     
    12601370                   (We don't want to waste heap by creating a directory instance per namespace.) */
    12611371                PRTFSISOMAKERDIR pChildObj = rtFsIsoMakerFindSubdirBySpec((PRTFSISOMAKERDIR)pParent->pObj,
    1262                                                                            pszPath, cchComponent, fNamespace);
     1372                                                                           pszPath, cchComponent, pNamespace->fNamespace);
    12631373                if (pChildObj)
    12641374                {
    1265                     PPRTFSISOMAKERNAME ppChildName = rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, fNamespace);
     1375                    PPRTFSISOMAKERNAME ppChildName = rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, pNamespace);
    12661376                    if (!*ppChildName)
    12671377                    {
    1268                         rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, ppChildName, pParent,
    1269                                                     pszPath, cchComponent, &pChild);
     1378                        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, pParent, pszPath, cchComponent, &pChild);
    12701379                        if (RT_FAILURE(rc))
    12711380                            return rc;
     
    12781387                    rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pChildObj);
    12791388                    if (RT_SUCCESS(rc))
    1280                         rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core,
    1281                                                     rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, fNamespace),
    1282                                                     pParent, pszPath, cchComponent, &pChild);
     1389                        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, pParent, pszPath, cchComponent, &pChild);
    12831390                    if (RT_FAILURE(rc))
    12841391                        return rc;
     
    13011408 * @returns IPRT status code.
    13021409 * @param   pThis           The ISO maker instance.
     1410 * @param   pNamespace      The namespace to name it in.
    13031411 * @param   pObj            The filesystem object to name.
    1304  * @param   fNamespace      The namespace to name it in.
    13051412 * @param   pszPath         The path to the entry in the namespace.
    1306  * @param   ppRoot          The namespace root.
    1307  * @param   ppName          The namespace name member in @a paEntry.
    1308  */
    1309 static int rtFsIsoMakerObjSetPathInOne(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, uint32_t fNamespace, const char *pszPath,
    1310                                        PPRTFSISOMAKERNAME ppRoot, PPRTFSISOMAKERNAME ppName)
    1311 {
    1312     AssertReturn(!*ppName, VERR_WRONG_ORDER);
     1413 */
     1414static int rtFsIsoMakerObjSetPathInOne(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace,
     1415                                       PRTFSISOMAKEROBJ pObj, const char *pszPath)
     1416{
     1417    AssertReturn(*rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace) == NULL, VERR_WRONG_ORDER);
    13131418    AssertReturn(RTPATH_IS_SLASH(*pszPath), VERR_INTERNAL_ERROR_5);
    13141419
     
    13221427    int                 rc;
    13231428    if (pszPath[1] != '\0')
    1324         rc = rtFsIsoMakerPathToParent(pThis, ppRoot, fNamespace, pszPath, &pParent, &pszEntry, &cchEntry);
     1429        rc = rtFsIsoMakerPathToParent(pThis, pNamespace, pszPath, &pParent, &pszEntry, &cchEntry);
    13251430    else
    13261431    {
     
    13291434         */
    13301435        Assert(pObj->enmType == RTFSISOMAKEROBJTYPE_DIR);
    1331         AssertReturn(!*ppRoot, VERR_WRONG_ORDER);
     1436        AssertReturn(pNamespace->pRoot == NULL, VERR_WRONG_ORDER);
    13321437        pszEntry = "/";
    13331438        cchEntry = 0;
     
    13431448        AssertReturn(!RTPATH_IS_SLASH(pszEntry[cchEntry]) || pObj->enmType == RTFSISOMAKEROBJTYPE_DIR,
    13441449                     VERR_NOT_A_DIRECTORY);
    1345         rc = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, ppName, pParent, pszEntry, cchEntry, NULL);
     1450        rc = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, pParent, pszEntry, cchEntry, NULL);
    13461451    }
    13471452    return rc;
     1453}
     1454
     1455
     1456/**
     1457 * Removes an object from the given namespace.
     1458 *
     1459 * @returns IPRT status code.
     1460 * @param   pThis       The ISO maker instance.
     1461 * @param   pNamespace  The namespace.
     1462 * @param   pObj        The object to name.
     1463 */
     1464static int rtFsIsoMakerObjUnsetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj)
     1465{
     1466    /*
     1467     * First check if there is anything to do here at all.
     1468     */
     1469    PPRTFSISOMAKERNAME ppName = rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace);
     1470    PRTFSISOMAKERNAME  pName = *ppName;
     1471    if (!pName)
     1472        return VINF_SUCCESS;
     1473
     1474    /*
     1475     * We don't support this on the root.
     1476     */
     1477    AssertReturn(pName->pParent, VERR_ACCESS_DENIED);
     1478
     1479    /*
     1480     * If this is a directory, we're in for some real fun here as we need to
     1481     * unset the names of all the children too.
     1482     */
     1483    PRTFSISOMAKERNAMEDIR pDir = pName->pDir;
     1484    if (pDir)
     1485    {
     1486        uint32_t iChild = pDir->cChildren;
     1487        while (iChild-- > 0)
     1488        {
     1489            int rc = rtFsIsoMakerObjUnsetName(pThis, pNamespace, pDir->papChildren[iChild]->pObj);
     1490            if (RT_FAILURE(rc))
     1491                return rc;
     1492        }
     1493        AssertReturn(pDir->cChildren == 0, VERR_DIR_NOT_EMPTY);
     1494    }
     1495
     1496    /*
     1497     * Unlink the pName from the parent.
     1498     */
     1499    pDir = pName->pParent->pDir;
     1500    uint32_t iChild = pDir->cChildren;
     1501    while (iChild-- > 0)
     1502        if (pDir->papChildren[iChild] == pName)
     1503        {
     1504            uint32_t cToMove = pDir->cChildren - iChild - 1;
     1505            if (cToMove > 0)
     1506                memmove(&pDir->papChildren[iChild], &pDir->papChildren[iChild + 1], cToMove * sizeof(pDir->papChildren[0]));
     1507            pDir->cChildren--;
     1508            pNamespace->cNames--;
     1509
     1510            /*
     1511             * NULL the name member in the object and free the structure.
     1512             */
     1513            *ppName = NULL;
     1514            RTMemFree(pName);
     1515
     1516            return VINF_SUCCESS;
     1517        }
     1518
     1519    /* Not found. This can't happen. */
     1520    AssertFailed();
     1521    return VERR_INTERNAL_ERROR_2;
    13481522}
    13491523
     
    13911565        return pObj;
    13921566    return rtFsIsoMakerIndexToObjSlow(pThis, idxObj);
     1567}
     1568
     1569
     1570/**
     1571 * Removes the specified object from the image.
     1572 *
     1573 * @returns IPRT status code.
     1574 * @param   hIsoMaker           The ISO maker instance.
     1575 * @param   idxObj              The index of the object to remove.
     1576 */
     1577RTDECL(int) RTFsIsoMakerObjRemove(RTFSISOMAKER hIsoMaker, uint32_t idxObj)
     1578{
     1579    /*
     1580     * Validate and translate input.
     1581     */
     1582    PRTFSISOMAKERINT pThis = hIsoMaker;
     1583    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     1584    PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj);
     1585    AssertReturn(pObj, VERR_OUT_OF_RANGE);
     1586
     1587    /*
     1588     * Remove the object from all name spaces.
     1589     */
     1590    int rc = VINF_SUCCESS;
     1591    for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++)
     1592    {
     1593        PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace);
     1594        int rc2 = rtFsIsoMakerObjUnsetName(pThis, pNamespace, pObj);
     1595        if (RT_SUCCESS(rc2) || RT_FAILURE(rc))
     1596            continue;
     1597            rc = rc2;
     1598    }
     1599
     1600    /*
     1601     * If that succeeded, remove the object itself.
     1602     */
     1603    if (RT_SUCCESS(rc))
     1604    {
     1605        RTListNodeRemove(&pObj->Entry);
     1606        if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE)
     1607        {
     1608            uint64_t cbData = ((PRTFSISOMAKERFILE)pObj)->cbData;
     1609            pThis->cbData -= RT_ALIGN_64(cbData, RTFSISOMAKER_SECTOR_SIZE);
     1610        }
     1611        pThis->cObjects--;
     1612        rtFsIsoMakerObjDestroy(pObj);
     1613    }
     1614
     1615    return rc;
    13931616}
    13941617
     
    14071630 * @param   fNamespaces         The namespaces to apply the path to
    14081631 *                              (RTFSISOMAKERNAMESPACE_XXX).
    1409  * @param   pszPath             The ISO-9660 path.
     1632 * @param   pszPath             The path.
    14101633 */
    14111634RTDECL(int) RTFsIsoMakerObjSetPath(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszPath)
     
    14291652        if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace)
    14301653        {
    1431             int rc2 = rtFsIsoMakerObjSetPathInOne(pThis, pObj, g_aRTFsIsoNamespaces[i].fNamespace, pszPath,
    1432                                                   (PPRTFSISOMAKERNAME)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offRoot),
    1433                                                   (PPRTFSISOMAKERNAME)((uintptr_t)pObj  + g_aRTFsIsoNamespaces[i].offName));
    1434             if (RT_SUCCESS(rc2) || RT_FAILURE(rc))
    1435                 continue;
    1436             rc = rc2;
     1654            PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace);
     1655            if (pNamespace->uLevel > 0)
     1656            {
     1657                int rc2 = rtFsIsoMakerObjSetPathInOne(pThis, pNamespace, pObj, pszPath);
     1658                if (RT_SUCCESS(rc2) || RT_FAILURE(rc))
     1659                    continue;
     1660                rc = rc2;
     1661            }
     1662        }
     1663    return rc;
     1664}
     1665
     1666
     1667/**
     1668 * Sets the name of an object in the selected namespaces, placing it under the
     1669 * given directory.
     1670 *
     1671 * The name will be transformed as necessary.
     1672 *
     1673 * The initial implementation does not allow this function to be called more
     1674 * than once on an object.
     1675 *
     1676 * @returns IPRT status code.
     1677 * @param   hIsoMaker           The ISO maker handle.
     1678 * @param   idxObj              The configuration index of to name.
     1679 * @param   idxParentObj        The parent directory object.
     1680 * @param   fNamespaces         The namespaces to apply the path to
     1681 *                              (RTFSISOMAKERNAMESPACE_XXX).
     1682 * @param   pszName             The name.
     1683 */
     1684RTDECL(int) RTFsIsoMakerObjSetNameAndParent(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t idxParentObj,
     1685                                            uint32_t fNamespaces, const char *pszName)
     1686{
     1687    /*
     1688     * Validate and translate input.
     1689     */
     1690    PRTFSISOMAKERINT pThis = hIsoMaker;
     1691    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     1692    AssertReturn(!(fNamespaces & ~RTFSISOMAKERNAMESPACE_VALID_MASK), VERR_INVALID_FLAGS);
     1693    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     1694    size_t cchName = strlen(pszName);
     1695    AssertReturn(cchName > 0, VERR_INVALID_NAME);
     1696    AssertReturn(memchr(pszName, '/', cchName) == NULL, VERR_INVALID_NAME);
     1697    PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj);
     1698    AssertReturn(pObj, VERR_OUT_OF_RANGE);
     1699    PRTFSISOMAKEROBJ pParentObj = rtFsIsoMakerIndexToObj(pThis, idxParentObj);
     1700    AssertReturn(pParentObj, VERR_OUT_OF_RANGE);
     1701
     1702    /*
     1703     * Execute requested actions.
     1704     */
     1705    int rc = VINF_SUCCESS;
     1706    for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++)
     1707        if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace)
     1708        {
     1709            PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace);
     1710            if (pNamespace->uLevel > 0)
     1711            {
     1712                PRTFSISOMAKERNAME pParentName = *rtFsIsoMakerObjGetNameForNamespace(pParentObj, pNamespace);
     1713                if (pParentName)
     1714                {
     1715                    int rc2 = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, pParentName, pszName, cchName, NULL /*ppNewName*/);
     1716                    if (RT_SUCCESS(rc2) || RT_FAILURE(rc))
     1717                        continue;
     1718                    rc = rc2;
     1719                }
     1720            }
    14371721        }
    14381722    return rc;
     
    14481732 * @param   pObj                The common object.
    14491733 * @param   enmType             The object type.
    1450  */
    1451 static int rtFsIsoMakerInitCommonObj(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, RTFSISOMAKEROBJTYPE enmType)
     1734 * @param   pObjInfo            The object information (typically source).
     1735 *                              Optional.
     1736 */
     1737static int rtFsIsoMakerInitCommonObj(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj,
     1738                                     RTFSISOMAKEROBJTYPE enmType, PCRTFSOBJINFO pObjInfo)
    14521739{
    14531740    AssertReturn(pThis->cObjects < RTFSISOMAKER_MAX_OBJECTS, VERR_OUT_OF_RANGE);
     
    14581745    pObj->pHfsName      = NULL;
    14591746    pObj->idxObj        = pThis->cObjects++;
     1747    if (pObjInfo)
     1748    {
     1749        pObj->BirthTime         = pObjInfo->BirthTime;
     1750        pObj->ChangeTime        = pObjInfo->ChangeTime;
     1751        pObj->ModificationTime  = pObjInfo->ModificationTime;
     1752        pObj->AccessedTime      = pObjInfo->AccessTime;
     1753        pObj->fMode             = pObjInfo->Attr.fMode;
     1754        pObj->uid               = pObjInfo->Attr.u.Unix.uid != NIL_RTUID ? pObjInfo->Attr.u.Unix.uid : pThis->uidDefault;
     1755        pObj->gid               = pObjInfo->Attr.u.Unix.gid != NIL_RTGID ? pObjInfo->Attr.u.Unix.gid : pThis->gidDefault;
     1756    }
     1757    else
     1758    {
     1759        pObj->BirthTime         = pThis->ImageCreationTime;
     1760        pObj->ChangeTime        = pThis->ImageCreationTime;
     1761        pObj->ModificationTime  = pThis->ImageCreationTime;
     1762        pObj->AccessedTime      = pThis->ImageCreationTime;
     1763        pObj->fMode             = enmType == RTFSISOMAKEROBJTYPE_DIR ? pThis->fDefaultDirMode : pThis->fDefaultFileMode;
     1764        pObj->uid               = pThis->uidDefault;
     1765        pObj->gid               = pThis->gidDefault;
     1766    }
     1767
    14601768    RTListAppend(&pThis->ObjectHead, &pObj->Entry);
    14611769    return VINF_SUCCESS;
     
    14741782    PRTFSISOMAKERDIR pDir = (PRTFSISOMAKERDIR)RTMemAllocZ(sizeof(*pDir));
    14751783    AssertReturn(pDir, VERR_NO_MEMORY);
    1476     int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR);
     1784    int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR, NULL);
    14771785    if (RT_SUCCESS(rc))
    14781786    {
     
    15381846                *pidxObj = idxObj;
    15391847        }
    1540         /** @todo else: back out later?  */
     1848        else
     1849            RTFsIsoMakerObjRemove(hIsoMaker, idxObj);
    15411850    }
    15421851    return rc;
    15431852}
    15441853
     1854
     1855/**
     1856 * Internal function for adding an unnamed file.
     1857 *
     1858 * @returns IPRT status code.
     1859 * @param   pThis               The ISO make instance.
     1860 * @param   cbExtra             Extra space for additional data (e.g. source
     1861 *                              path string copy).
     1862 * @param   ppFile              Where to return the file.
     1863 */
     1864static int rtFsIsoMakerAddUnnamedFileWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, size_t cbExtra,
     1865                                            PRTFSISOMAKERFILE *ppFile)
     1866{
     1867    PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)RTMemAllocZ(sizeof(*pFile) + cbExtra);
     1868    AssertReturn(pFile, VERR_NO_MEMORY);
     1869    int rc = rtFsIsoMakerInitCommonObj(pThis, &pFile->Core, RTFSISOMAKEROBJTYPE_FILE, pObjInfo);
     1870    if (RT_SUCCESS(rc))
     1871    {
     1872        pFile->cbData       = pObjInfo->cbObject;
     1873        pThis->cbData += RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE);
     1874        pFile->offData      = UINT64_MAX;
     1875        pFile->enmSrcType   = RTFSISOMAKERSRCTYPE_INVALID;
     1876        pFile->u.pszSrcPath = NULL;
     1877
     1878        *ppFile = pFile;
     1879        return VINF_SUCCESS;
     1880    }
     1881    RTMemFree(pFile);
     1882    return rc;
     1883
     1884}
     1885
     1886
     1887/**
     1888 * Adds an unnamed file to the image that's backed by a host file.
     1889 *
     1890 * The file must explictly be entered into the desired namespaces.
     1891 *
     1892 * @returns IPRT status code
     1893 * @param   hIsoMaker           The ISO maker handle.
     1894 * @param   pszSrcFile          The source file path.  VFS chain spec allowed.
     1895 * @param   pidxObj             Where to return the configuration index of the
     1896 *                              directory.
     1897 * @sa      RTFsIsoMakerAddFile, RTFsIsoMakerObjSetPath
     1898 */
     1899RTDECL(int) RTFsIsoMakerAddUnnamedFileWithSrcPath(RTFSISOMAKER hIsoMaker, const char *pszSrcFile, uint32_t *pidxObj)
     1900{
     1901    PRTFSISOMAKERINT pThis = hIsoMaker;
     1902    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     1903    AssertPtrReturn(pidxObj, VERR_INVALID_POINTER);
     1904    *pidxObj = UINT32_MAX;
     1905
     1906    /*
     1907     * Check that the source file exists and is a file.
     1908     */
     1909    uint32_t    offError = 0;
     1910    RTFSOBJINFO ObjInfo;
     1911    int rc = RTVfsChainQueryInfo(pszSrcFile, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK, &offError, NULL);
     1912    AssertMsgRCReturn(rc, ("%s -> %Rrc offError=%u\n", pszSrcFile, rc, offError), rc);
     1913    AssertMsgReturn(RTFS_IS_FILE(ObjInfo.Attr.fMode), ("%#x - %s\n", ObjInfo.Attr.fMode, pszSrcFile), VERR_NOT_A_FILE);
     1914
     1915    /*
     1916     * Create a file object for it.
     1917     */
     1918    size_t const      cbSrcFile = strlen(pszSrcFile) + 1;
     1919    PRTFSISOMAKERFILE pFile;
     1920    rc = rtFsIsoMakerAddUnnamedFileWorker(pThis, &ObjInfo, cbSrcFile, &pFile);
     1921    if (RT_SUCCESS(rc))
     1922    {
     1923        pFile->enmSrcType   = RTFSISOMAKERSRCTYPE_PATH;
     1924        pFile->u.pszSrcPath = (char *)memcpy(pFile + 1, pszSrcFile, cbSrcFile);
     1925
     1926        *pidxObj = pFile->Core.idxObj;
     1927    }
     1928    return rc;
     1929}
     1930
     1931
     1932/**
     1933 * Adds an unnamed file to the image that's backed by a VFS file.
     1934 *
     1935 * The file must explictly be entered into the desired namespaces.
     1936 *
     1937 * @returns IPRT status code
     1938 * @param   hIsoMaker           The ISO maker handle.
     1939 * @param   hVfsFileSrc         The source file handle.
     1940 * @param   pidxObj             Where to return the configuration index of the
     1941 *                              directory.
     1942 * @sa      RTFsIsoMakerAddUnnamedFileWithSrcPath, RTFsIsoMakerObjSetPath
     1943 */
     1944RTDECL(int) RTFsIsoMakerAddUnnamedFileWithVfsFile(RTFSISOMAKER hIsoMaker, RTVFSFILE hVfsFileSrc, uint32_t *pidxObj)
     1945{
     1946    PRTFSISOMAKERINT pThis = hIsoMaker;
     1947    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     1948    AssertPtrReturn(pidxObj, VERR_INVALID_POINTER);
     1949    *pidxObj = UINT32_MAX;
     1950
     1951    /*
     1952     * Get the VFS file info.  This implicitly validates the handle.
     1953     */
     1954    RTFSOBJINFO ObjInfo;
     1955    int rc = RTVfsFileQueryInfo(hVfsFileSrc, &ObjInfo, RTFSOBJATTRADD_UNIX);
     1956    AssertMsgRCReturn(rc, ("RTVfsFileQueryInfo(%p) -> %Rrc\n", hVfsFileSrc, rc), rc);
     1957
     1958    /*
     1959     * Retain a reference to the file.
     1960     */
     1961    uint32_t cRefs = RTVfsFileRetain(hVfsFileSrc);
     1962    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     1963
     1964    /*
     1965     * Create a file object for it.
     1966     */
     1967    PRTFSISOMAKERFILE pFile;
     1968    rc = rtFsIsoMakerAddUnnamedFileWorker(pThis, &ObjInfo, 0, &pFile);
     1969    if (RT_SUCCESS(rc))
     1970    {
     1971        pFile->enmSrcType = RTFSISOMAKERSRCTYPE_VFS_FILE;
     1972        pFile->u.hVfsFile = hVfsFileSrc;
     1973
     1974        *pidxObj = pFile->Core.idxObj;
     1975    }
     1976    else
     1977        RTVfsFileRelease(hVfsFileSrc);
     1978    return rc;
     1979}
     1980
     1981
     1982/**
     1983 * Adds a file that's backed by a host file to the image in all namespaces and
     1984 * with attributes taken from the source file.
     1985 *
     1986 * @returns IPRT status code
     1987 * @param   hIsoMaker       The ISO maker handle.
     1988 * @param   pszFile         The path to the file in the image.
     1989 * @param   pszSrcFile      The source file path.  VFS chain spec allowed.
     1990 * @param   pidxObj         Where to return the configuration index of the file.
     1991 *                          Optional
     1992 * @sa      RTFsIsoMakerAddFileWithVfsFile,
     1993 *          RTFsIsoMakerAddUnnamedFileWithSrcPath
     1994 */
     1995RTDECL(int) RTFsIsoMakerAddFileWithSrcPath(RTFSISOMAKER hIsoMaker, const char *pszFile, const char *pszSrcFile, uint32_t *pidxObj)
     1996{
     1997    PRTFSISOMAKERINT pThis = hIsoMaker;
     1998    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     1999    AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
     2000    AssertReturn(RTPATH_IS_SLASH(*pszFile), VERR_INVALID_NAME);
     2001
     2002    uint32_t idxObj;
     2003    int rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(hIsoMaker, pszSrcFile, &idxObj);
     2004    if (RT_SUCCESS(rc))
     2005    {
     2006        rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKERNAMESPACE_ALL, pszFile);
     2007        if (RT_SUCCESS(rc))
     2008        {
     2009            if (pidxObj)
     2010                *pidxObj = idxObj;
     2011        }
     2012        else
     2013            RTFsIsoMakerObjRemove(hIsoMaker, idxObj);
     2014    }
     2015    return rc;
     2016}
     2017
     2018
     2019/**
     2020 * Adds a file that's backed by a VFS file to the image in all namespaces and
     2021 * with attributes taken from the source file.
     2022 *
     2023 * @returns IPRT status code
     2024 * @param   hIsoMaker       The ISO maker handle.
     2025 * @param   pszFile         The path to the file in the image.
     2026 * @param   hVfsFileSrc     The source file handle.
     2027 * @param   pidxObj         Where to return the configuration index of the file.
     2028 *                          Optional.
     2029 * @sa      RTFsIsoMakerAddUnnamedFileWithVfsFile,
     2030 *          RTFsIsoMakerAddFileWithSrcPath
     2031 */
     2032RTDECL(int) RTFsIsoMakerAddFileWithVfsFile(RTFSISOMAKER hIsoMaker, const char *pszFile, RTVFSFILE hVfsFileSrc, uint32_t *pidxObj)
     2033{
     2034    PRTFSISOMAKERINT pThis = hIsoMaker;
     2035    RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
     2036    AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
     2037    AssertReturn(RTPATH_IS_SLASH(*pszFile), VERR_INVALID_NAME);
     2038
     2039    uint32_t idxObj;
     2040    int rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(hIsoMaker, hVfsFileSrc, &idxObj);
     2041    if (RT_SUCCESS(rc))
     2042    {
     2043        rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKERNAMESPACE_ALL, pszFile);
     2044        if (RT_SUCCESS(rc))
     2045        {
     2046            if (pidxObj)
     2047                *pidxObj = idxObj;
     2048        }
     2049        else
     2050            RTFsIsoMakerObjRemove(hIsoMaker, idxObj);
     2051    }
     2052    return rc;
     2053}
     2054
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