VirtualBox

Changeset 67339 in vbox for trunk


Ignore:
Timestamp:
Jun 12, 2017 11:38:33 AM (7 years ago)
Author:
vboxsync
Message:

IPRT: More ISO maker code.

Location:
trunk
Files:
2 edited

Legend:

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

    r67326 r67339  
    222222typedef struct ISO9660PATHREC
    223223{
    224     /** 0x00: Length of this record in bytes. */
     224    /** 0x00: Length of the achDirId field in bytes. */
    225225    uint8_t             cbDirId;
    226226    /** 0x01: Extended attribute record length in bytes? */
     
    242242AssertCompileMemberOffset(ISO9660PATHREC, idParentRec, 0x06);
    243243AssertCompileMemberOffset(ISO9660PATHREC, achDirId,   0x08);
     244/** Pointer to an ISO 9660 path table record. */
     245typedef ISO9660PATHREC *PISO9660PATHREC;
     246/** Pointer to a const ISO 9660 path table record. */
     247typedef ISO9660PATHREC const *PCISO9660PATHREC;
    244248
    245249
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67332 r67339  
    8787
    8888
     89/** Calculates the path table record size given the name length. */
     90#define RTFSISOMAKER_CALC_PATHREC_SIZE(a_cbNameInDirRec) \
     91    ( RT_UOFFSETOF(ISO9660PATHREC, achDirId[(a_cbNameInDirRec)]) + ((a_cbNameInDirRec) & 1) )
     92
    8993
    9094/*********************************************************************************************************************************
     
    9397/** Pointer to an ISO maker object name space node. */
    9498typedef struct RTFSISOMAKERNAME *PRTFSISOMAKERNAME;
     99/** Pointer to a const ISO maker object name space node. */
     100typedef struct RTFSISOMAKERNAME const *PCRTFSISOMAKERNAME;
    95101/** Pointer to an ISO maker object name space node pointer. */
    96102typedef PRTFSISOMAKERNAME *PPRTFSISOMAKERNAME;
     103
    97104/** Pointer to a common ISO image maker file system object. */
    98105typedef struct RTFSISOMAKEROBJ *PRTFSISOMAKEROBJ;
     106/** Pointer to a const common ISO image maker file system object. */
     107typedef struct RTFSISOMAKEROBJ const *PCRTFSISOMAKEROBJ;
     108
    99109/** Pointer to a ISO maker file object. */
    100110typedef struct RTFSISOMAKERFILE *PRTFSISOMAKERFILE;
     111/** Pointer to a const ISO maker file object. */
     112typedef struct RTFSISOMAKERFILE const *PCRTFSISOMAKERFILE;
    101113
    102114
     
    147159    * This is set when finalizing the image.  */
    148160    uint16_t                idPathTable;
     161    /** The size of the first directory record (0x00 - '.'). */
     162    uint8_t                 cbDirRec00;
     163    /** The size of the second directory record (0x01 - '..'). */
     164    uint8_t                 cbDirRec01;
    149165    /** Pointer to back to the namespace node this belongs to (for the finalized
    150166     *  entry list). */
     
    153169    RTLISTNODE              FinalizedEntry;
    154170} RTFSISOMAKERNAMEDIR;
    155 /** Pointer to directory specfic name space node info. */
     171/** Pointer to directory specfic namespace node info. */
    156172typedef RTFSISOMAKERNAMEDIR *PRTFSISOMAKERNAMEDIR;
     173/** Pointer to const directory specfic namespace node info. */
     174typedef const RTFSISOMAKERNAMEDIR *PCRTFSISOMAKERNAMEDIR;
    157175
    158176
     
    17911809                pDir->offPathTable  = UINT32_MAX;
    17921810                pDir->idPathTable   = UINT16_MAX;
     1811                pDir->cbDirRec00    = 0;
     1812                pDir->cbDirRec01    = 0;
    17931813                RTListInit(&pDir->FinalizedEntry);
    17941814                pName->pDir = pDir;
     
    29062926               with a 1 byte name (00 or 01). */
    29072927            Assert(pCurName->cbDirRec != 0);
    2908             uint32_t offInDir = pCurName->cbDirRec    - pCurName->cbNameInDirRec    + 1;
    2909             offInDir         += pParentName->cbDirRec - pParentName->cbNameInDirRec + 1;
     2928            Assert(pParentName->cbDirRec != 0);
     2929            pCurDir->cbDirRec00 = pCurName->cbDirRec    - pCurName->cbNameInDirRec    - !(pCurName->cbNameInDirRec    & 1) + 1;
     2930            pCurDir->cbDirRec01 = pParentName->cbDirRec - pParentName->cbNameInDirRec - !(pParentName->cbNameInDirRec & 1) + 1;
     2931
     2932            uint32_t offInDir   = (uint32_t)pCurDir->cbDirRec00 + pCurDir->cbDirRec01;
    29102933
    29112934            /* Finalize the directory entries. */
     
    29402963            pCurDir->offPathTable = cbPathTable;
    29412964            pCurDir->idPathTable  = idPathTable++;
    2942             cbPathTable += RT_OFFSETOF(ISO9660PATHREC, achDirId[pCurName->cbNameInDirRec]) + (pCurName->cbNameInDirRec & 1);
     2965            cbPathTable += RTFSISOMAKER_CALC_PATHREC_SIZE(pCurName->cbNameInDirRec);
    29432966        }
    29442967    }
     
    37183741
    37193742
    3720 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace,
    3721                                                  PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, bool fLittleEndian,
    3722                                                  uint32_t offInTable, uint8_t *pbBuf, size_t cbBuf)
    3723 {
    3724     RT_NOREF(pThis, pNamespace, pFinalizedDirs, fLittleEndian, offInTable, pbBuf, cbBuf);
    3725     return 0;
    3726 }
    3727 
    3728 
    3729 static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, uint8_t *pbBuf)
    3730 {
    3731     memset(pbBuf, pName->szName[0], sizeof(ISO9660DIRREC));
     3743/**
     3744 * Generates ISO-9660 path table record into the specified buffer.
     3745 *
     3746 * @returns Number of bytes copied into the buffer.
     3747 * @param   pName       The directory namespace node.
     3748 * @param   fUnicode    Set if the name should be translated to big endian
     3749 *                      UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     3750 * @param   pbBuf       The buffer.  This is large enough to hold the path
     3751 *                      record (use RTFSISOMAKER_CALC_PATHREC_SIZE) and a zero
     3752 *                      RTUTF16 terminator if @a fUnicode is true.
     3753 */
     3754static uint32_t rtFsIsoMakerOutFile_GeneratePathRec(PRTFSISOMAKERNAME pName, bool fUnicode, bool fLittleEndian, uint8_t *pbBuf)
     3755{
     3756    PISO9660PATHREC pPathRec = (PISO9660PATHREC)pbBuf;
     3757    pPathRec->cbDirId   = pName->cbNameInDirRec;
     3758    pPathRec->cbExtAttr = 0;
     3759    if (fLittleEndian)
     3760    {
     3761        pPathRec->offExtent   = RT_H2LE_U32(pName->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE);
     3762        pPathRec->idParentRec = RT_H2LE_U16(pName->pParent ? pName->pParent->pDir->idPathTable : 0);
     3763    }
     3764    else
     3765    {
     3766        pPathRec->offExtent   = RT_H2BE_U32(pName->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE);
     3767        pPathRec->idParentRec = RT_H2BE_U16(pName->pParent ? pName->pParent->pDir->idPathTable : 0);
     3768    }
     3769    if (!fUnicode)
     3770    {
     3771        memcpy(&pPathRec->achDirId[0], pName->szName, pName->cbNameInDirRec);
     3772        if (pName->cbNameInDirRec & 1)
     3773            pPathRec->achDirId[pName->cbNameInDirRec] = '\0';
     3774    }
     3775    else
     3776    {
     3777        /* Caller made sure there is space for a zero terminator character. */
     3778        PRTUTF16 pwszTmp   = (PRTUTF16)&pPathRec->achDirId[0];
     3779        size_t   cwcResult = 0;
     3780        int rc = RTStrToUtf16BigEx(pName->szName, RTSTR_MAX, &pwszTmp, pName->cbNameInDirRec / sizeof(RTUTF16) + 1, &cwcResult);
     3781        AssertRC(rc);
     3782        Assert(cwcResult * sizeof(RTUTF16) == pName->cbNameInDirRec);
     3783    }
     3784    return RTFSISOMAKER_CALC_PATHREC_SIZE(pName->cbNameInDirRec);
     3785}
     3786
     3787
     3788/**
     3789 * Deals with situations where the destination buffer doesn't cover the whole
     3790 * path table record.
     3791 *
     3792 * @returns Number of bytes copied into the buffer.
     3793 * @param   pName       The directory namespace node.
     3794 * @param   fUnicode    Set if the name should be translated to big endian
     3795 *                      UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     3796 * @param   offInRec    The offset into the path table record.
     3797 * @param   pbBuf       The buffer.
     3798 * @param   cbBuf       The buffer size.
     3799 */
     3800static uint32_t rtFsIsoMakerOutFile_GeneratePathRecPartial(PRTFSISOMAKERNAME pName, bool fUnicode, bool fLittleEndian,
     3801                                                           uint32_t offInRec, uint8_t *pbBuf, size_t cbBuf)
     3802{
     3803    uint8_t abTmpRec[256];
     3804    size_t cbToCopy = rtFsIsoMakerOutFile_GeneratePathRec(pName, fUnicode, fLittleEndian, abTmpRec);
     3805    cbToCopy = RT_MIN(cbBuf, cbToCopy - offInRec);
     3806    memcpy(pbBuf, &abTmpRec[offInRec], cbToCopy);
     3807    return (uint32_t)cbToCopy;
     3808}
     3809
     3810
     3811/**
     3812 * Generate path table records.
     3813 *
     3814 * This will generate record up to the end of the table.  However, it will not
     3815 * supply the zero padding in the last sector, the caller is expected to take
     3816 * care of that.
     3817 *
     3818 * @returns Number of bytes written to the buffer.
     3819 * @param   pThis           The instance data for the VFS file.  We use this to
     3820 *                          keep hints about where we are and we which source
     3821 *                          file we've opened/created.
     3822 * @param   pFinalizedDirs  The finalized directory data for the namespace.
     3823 * @param   fUnicode        Set if the name should be translated to big endian
     3824 *                          UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     3825 * @param   fLittleEndian   Set if we're generating little endian records, clear
     3826 *                          if big endian records.
     3827 * @param   offInTable      Offset into the path table.
     3828 * @param   pbBuf           The output buffer.
     3829 * @param   cbBuf           The buffer size.
     3830 */
     3831static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,
     3832                                                bool fUnicode, bool fLittleEndian, uint32_t offInTable,
     3833                                                uint8_t *pbBuf, size_t cbBuf)
     3834{
     3835    /*
     3836     * Figure out which directory to start with.  We keep a hint in the instance.
     3837     */
     3838    PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint;
     3839    if (!pDir)
     3840    {
     3841        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3842        AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
     3843    }
     3844    if (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec))
     3845    { /* hit */ }
     3846    /* Seek forwards: */
     3847    else if (offInTable > pDir->offPathTable)
     3848        do
     3849        {
     3850            pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3851            AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
     3852        } while (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec));
     3853    /* Back to the start: */
     3854    else if (offInTable == 0)
     3855    {
     3856        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3857        AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
     3858    }
     3859    /* Seek backwards: */
     3860    else
     3861        do
     3862        {
     3863            pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3864            AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
     3865        } while (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec));
     3866
     3867    /*
     3868     * Generate content.
     3869     */
     3870    size_t cbDone = 0;
     3871    while (   cbBuf > 0
     3872           && pDir)
     3873    {
     3874        PRTFSISOMAKERNAME pName = pDir->pName;
     3875        uint8_t           cbRec = RTFSISOMAKER_CALC_PATHREC_SIZE(pName->cbNameInDirRec);
     3876        uint32_t          cbCopied;
     3877        if (   offInTable == pDir->offPathTable
     3878            && cbBuf      >= cbRec + fUnicode * 2U)
     3879            cbCopied = rtFsIsoMakerOutFile_GeneratePathRec(pName, fUnicode, fLittleEndian, pbBuf);
     3880        else
     3881            cbCopied = rtFsIsoMakerOutFile_GeneratePathRecPartial(pName, fUnicode, fLittleEndian,
     3882                                                                  offInTable - pDir->offPathTable, pbBuf, cbBuf);
     3883        cbDone     += cbCopied;
     3884        offInTable += cbCopied;
     3885        pbBuf      += cbCopied;
     3886        cbBuf      -= cbCopied;
     3887        pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
     3888    }
     3889
     3890    /*
     3891     * Update the hint.
     3892     */
     3893    pThis->pDirHint = pDir;
     3894
     3895    return cbDone;
     3896}
     3897
     3898
     3899/**
     3900 * Generates ISO-9660 directory record into the specified buffer.
     3901 *
     3902 * @returns Number of bytes copied into the buffer.
     3903 * @param   pName       The namespace node.
     3904 * @param   fUnicode    Set if the name should be translated to big endian
     3905 *                      UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     3906 * @param   pbBuf       The buffer.  This is at least pName->cbDirRec bytes big.
     3907 */
     3908static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t *pbBuf)
     3909{
     3910    /*
     3911     * Emit a standard ISO-9660 directory record.
     3912     */
     3913    PISO9660DIRREC          pDirRec = (PISO9660DIRREC)pbBuf;
     3914    PCRTFSISOMAKEROBJ       pObj    = pName->pObj;
     3915    PCRTFSISOMAKERNAMEDIR   pDir    = pName->pDir;
     3916    if (pDir)
     3917    {
     3918        pDirRec->offExtent.be       = RT_H2BE_U32(pDir->offDir / RTFSISOMAKER_SECTOR_SIZE);
     3919        pDirRec->offExtent.le       = RT_H2LE_U32(pDir->offDir / RTFSISOMAKER_SECTOR_SIZE);
     3920        pDirRec->cbData.be          = RT_H2BE_U32(pDir->cbDir);
     3921        pDirRec->cbData.le          = RT_H2LE_U32(pDir->cbDir);
     3922        pDirRec->fFileFlags         = ISO9660_FILE_FLAGS_DIRECTORY;
     3923    }
     3924    else if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE)
     3925    {
     3926        PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj;
     3927        pDirRec->offExtent.be       = RT_H2BE_U32(pFile->offData / RTFSISOMAKER_SECTOR_SIZE);
     3928        pDirRec->offExtent.le       = RT_H2LE_U32(pFile->offData / RTFSISOMAKER_SECTOR_SIZE);
     3929        pDirRec->cbData.be          = RT_H2BE_U32(pFile->cbData);
     3930        pDirRec->cbData.le          = RT_H2LE_U32(pFile->cbData);
     3931        pDirRec->fFileFlags         = 0;
     3932    }
     3933    else
     3934    {
     3935        pDirRec->offExtent.be       = 0;
     3936        pDirRec->offExtent.le       = 0;
     3937        pDirRec->cbData.be          = 0;
     3938        pDirRec->cbData.le          = 0;
     3939        pDirRec->fFileFlags         = 0;
     3940    }
     3941    rtFsIsoMakerTimespecToIso9660RecTimestamp(&pObj->BirthTime, &pDirRec->RecTime);
     3942
     3943    pDirRec->cbDirRec               = pName->cbDirRec;
     3944    pDirRec->cExtAttrBlocks         = 0;
     3945    pDirRec->bFileUnitSize          = 0;
     3946    pDirRec->bInterleaveGapSize     = 0;
     3947    pDirRec->VolumeSeqNo.be         = RT_H2BE_U16_C(1);
     3948    pDirRec->VolumeSeqNo.le         = RT_H2BE_U16_C(1);
     3949    pDirRec->bFileIdLength          = pName->cbNameInDirRec;
     3950
     3951    if (!fUnicode)
     3952    {
     3953        memcpy(&pDirRec->achFileId[0], pName->szName, pName->cbNameInDirRec);
     3954        if (!(pName->cbNameInDirRec & 1))
     3955            pDirRec->achFileId[pName->cbNameInDirRec] = '\0';
     3956    }
     3957    else
     3958    {
     3959        /* Convert to big endian UTF-16.  We're using a separate buffer here
     3960           because of zero terminator (none in pDirRec) and misalignment. */
     3961        RTUTF16  wszTmp[128];
     3962        PRTUTF16 pwszTmp = &wszTmp[0];
     3963        size_t   cwcResult = 0;
     3964        int rc = RTStrToUtf16BigEx(pName->szName, RTSTR_MAX, &pwszTmp, RT_ELEMENTS(wszTmp), &cwcResult);
     3965        AssertRC(rc);
     3966        Assert(cwcResult * sizeof(RTUTF16) == pName->cbNameInDirRec);
     3967        memcpy(&pDirRec->achFileId[0], pwszTmp, pName->cbNameInDirRec);
     3968        pDirRec->achFileId[pName->cbNameInDirRec] = '\0';
     3969    }
     3970
     3971    /*
     3972     * Rock ridge fields if enabled.
     3973     */
     3974    /** @todo rock ridge. */
     3975
    37323976    return pName->cbDirRec;
    37333977}
    37343978
    37353979
    3736 static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, uint32_t off, uint8_t *pbBuf, size_t cbBuf)
     3980/**
     3981 * Deals with situations where the destination buffer doesn't cover the whole
     3982 * directory record.
     3983 *
     3984 * @returns Number of bytes copied into the buffer.
     3985 * @param   pName       The namespace node.
     3986 * @param   fUnicode    Set if the name should be translated to big endian
     3987 *                      UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     3988 * @param   off         The offset into the directory record.
     3989 * @param   pbBuf       The buffer.
     3990 * @param   cbBuf       The buffer size.
     3991 */
     3992static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, bool fUnicode,
     3993                                                          uint32_t off, uint8_t *pbBuf, size_t cbBuf)
    37373994{
    37383995    Assert(off < pName->cbDirRec);
    37393996
    37403997    uint8_t abTmpBuf[256];
    3741     size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, pbBuf);
     3998    size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf);
    37423999    cbToCopy = RT_MIN(cbBuf, cbToCopy - off);
    37434000    memcpy(pbBuf, &abTmpBuf[off], cbToCopy);
     
    37464003
    37474004
     4005/**
     4006 * Generate a '.' or '..' directory record.
     4007 *
     4008 * This is the same as rtFsIsoMakerOutFile_GenerateDirRec, but with the filename
     4009 * reduced to 1 byte.
     4010 *
     4011 * @returns Number of bytes copied into the buffer.
     4012 * @param   pName       The directory namespace node.
     4013 * @param   fUnicode    Set if the name should be translated to big endian
     4014 *                      UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     4015 * @param   bDirId      The directory ID (0x00 or 0x01).
     4016 * @param   off         The offset into the directory record.
     4017 * @param   pbBuf       The buffer.
     4018 * @param   cbBuf       The buffer size.
     4019 */
     4020static uint32_t rtFsIsoMakerOutFile_GenerateSpecialDirRec(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t bDirId,
     4021                                                          uint32_t off, uint8_t *pbBuf, size_t cbBuf)
     4022{
     4023    Assert(off < pName->cbDirRec);
     4024    Assert(pName->pDir);
     4025
     4026    /* Generate a regular directory record. */
     4027    uint8_t abTmpBuf[256];
     4028    size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf);
     4029
     4030    /* Replace the filename part. */
     4031    PISO9660DIRREC pDirRec = (PISO9660DIRREC)abTmpBuf;
     4032    if (pDirRec->bFileIdLength != 1)
     4033    {
     4034        uint8_t offSysUse = pDirRec->bFileIdLength + !(pDirRec->bFileIdLength & 1) + RT_OFFSETOF(ISO9660DIRREC, achFileId);
     4035        uint8_t cbSysUse  = pDirRec->cbDirRec - offSysUse;
     4036        if (cbSysUse > 0)
     4037            memmove(&pDirRec->achFileId[1], &pbBuf[offSysUse], cbSysUse);
     4038        pDirRec->bFileIdLength = 1;
     4039        cbToCopy = RT_OFFSETOF(ISO9660DIRREC, achFileId) + 1 + cbSysUse;
     4040        pDirRec->cbDirRec = (uint8_t)cbToCopy;
     4041    }
     4042    pDirRec->achFileId[0] = bDirId;
     4043
     4044    /* Do the copying. */
     4045    cbToCopy = RT_MIN(cbBuf, cbToCopy - off);
     4046    memcpy(pbBuf, &abTmpBuf[off], cbToCopy);
     4047    return (uint32_t)cbToCopy;
     4048}
     4049
     4050
     4051/**
     4052 * Read directory records.
     4053 *
     4054 * This locates the directory at @a offUnsigned and generates directory records
     4055 * for it.  Caller must repeat the call to get directory entries for the next
     4056 * directory should there be desire for that.
     4057 *
     4058 * @returns Number of bytes copied into @a pbBuf.
     4059 * @param   pThis           The instance data for the VFS file.  We use this to
     4060 *                          keep hints about where we are and we which source
     4061 *                          file we've opened/created.
     4062 * @param   pIsoMaker       The ISO maker instance.
     4063 * @param   pFinalizedDirs  The finalized directory data for the namespace.
     4064 * @param   fUnicode        Set if the name should be translated to big endian
     4065 *                          UTF-16 / UCS-2, i.e. we're in the joliet namespace.
     4066 * @param   offUnsigned     The ISO image byte offset of the requested data.
     4067 * @param   pbBuf           The output buffer.
     4068 * @param   cbBuf           How much to read.
     4069 */
    37484070static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,
    3749                                                  uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf)
    3750 {
    3751 
     4071                                                 bool fUnicode, uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf)
     4072{
    37524073    /*
    37534074     * Figure out which directory.  We keep a hint in the instance.
     
    37584079    {
    37594080        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
    3760         AssertReturn(pDir, 0);
     4081        AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
    37614082    }
    37624083    if ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE))
     
    37674088        {
    37684089            pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
    3769             AssertReturn(pDir, 0);
     4090            AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
    37704091        } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE));
    37714092    /* Back to the start: */
     
    37734094    {
    37744095        pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry);
    3775         AssertReturn(pDir, 0);
     4096        AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
    37764097    }
    37774098    /* Seek backwards: */
     
    37804101        {
    37814102            pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry);
    3782             AssertReturn(pDir, 0);
     4103            AssertReturnStmt(pDir, *pbBuf = 0xff, 1);
    37834104        } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE));
    37844105
     
    37974118        PRTFSISOMAKERNAME   pDirName      = pDir->pName;
    37984119        PRTFSISOMAKERNAME   pParentName   = pDirName->pParent ? pDirName->pParent : pDirName;
    3799         uint32_t            cbSpecialRecs = pDirName->cbDirRec + pParentName->cbDirRec;
     4120        uint32_t            cbSpecialRecs = (uint32_t)pDir->cbDirRec00 + pDir->cbDirRec01;
    38004121
    38014122        /*
     
    38064127        {
    38074128            /* do '.' */
    3808             if (offInDir < pDirName->cbDirRec)
     4129            if (offInDir < pDir->cbDirRec00)
    38094130            {
    3810                 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pDirName, offInDir, pbBuf, cbBuf);
     4131                uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateSpecialDirRec(pDirName, fUnicode, 0, offInDir, pbBuf, cbBuf);
    38114132                cbDone   += cbCopied;
    38124133                offInDir += cbCopied;
     4134                pbBuf    += cbCopied;
    38134135                cbBuf    -= cbCopied;
    38144136            }
     
    38174139            if (cbBuf > 0)
    38184140            {
    3819                 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pParentName, offInDir - pDirName->cbDirRec,
    3820                                                                               pbBuf, cbBuf);
     4141                uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateSpecialDirRec(pParentName, fUnicode, 1,
     4142                                                                              offInDir - pDir->cbDirRec00, pbBuf, cbBuf);
    38214143                cbDone   += cbCopied;
    38224144                offInDir += cbCopied;
     4145                pbBuf    += cbCopied;
    38234146                cbBuf    -= cbCopied;
    38244147            }
     
    38414164                iChild++;
    38424165            }
    3843             AssertReturn(iChild < pDir->cChildren, 0);
     4166            AssertReturnStmt(iChild < pDir->cChildren, *pbBuf = 0xff, 1);
    38444167        }
    38454168
     
    38544177            if (   offInDir == pChild->offDirRec
    38554178                && cbBuf    >= pChild->cbDirRec)
    3856                 cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, pbBuf);
     4179                cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, fUnicode, pbBuf);
    38574180            else
    3858                 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, offInDir - pChild->offDirRec, pbBuf, cbBuf);
     4181                cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, fUnicode, offInDir - pChild->offDirRec, pbBuf, cbBuf);
    38594182            cbDone   += cbCopied;
    38604183            offInDir += cbCopied;
     4184            pbBuf    += cbCopied;
    38614185            cbBuf    -= cbCopied;
     4186            iChild++;
    38624187        }
    38634188
     
    38834208
    38844209
     4210/**
     4211 * Read directory records or path table records.
     4212 *
     4213 * Will not necessarily fill the entire buffer.  Caller must call again to get
     4214 * more.
     4215 *
     4216 * @returns Number of bytes copied into @a pbBuf.
     4217 * @param   pThis           The instance data for the VFS file.  We use this to
     4218 *                          keep hints about where we are and we which source
     4219 *                          file we've opened/created.
     4220 * @param   pIsoMaker       The ISO maker instance.
     4221 * @param   pNamespace      The namespace.
     4222 * @param   pFinalizedDirs  The finalized directory data for the namespace.
     4223 * @param   offUnsigned     The ISO image byte offset of the requested data.
     4224 * @param   pbBuf           The output buffer.
     4225 * @param   cbBuf           How much to read.
     4226 */
    38854227static size_t rtFsIsoMakerOutFile_ReadDirStructures(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace,
    38864228                                                    PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,
    3887                                                     uint64_t off, uint8_t *pbBuf, size_t cbBuf)
    3888 {
    3889     if (off < pFinalizedDirs->offPathTableL)
    3890         return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, off, pbBuf, cbBuf);
    3891     if (off < pFinalizedDirs->offPathTableM)
    3892         return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, true /*fLittleEndian*/,
    3893                                                  (uint32_t)(off - pFinalizedDirs->offPathTableL), pbBuf, cbBuf);
    3894     return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, false /*fLittleEndian*/,
    3895                                              (uint32_t)(off - pFinalizedDirs->offPathTableM), pbBuf, cbBuf);
     4229                                                    uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf)
     4230{
     4231    if (offUnsigned < pFinalizedDirs->offPathTableL)
     4232        return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET,
     4233                                                  offUnsigned, pbBuf, cbBuf);
     4234
     4235    uint64_t offInTable;
     4236    if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableL) < pFinalizedDirs->cbPathTable)
     4237        return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET,
     4238                                                 true /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf);
     4239
     4240    if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableM) < pFinalizedDirs->cbPathTable)
     4241        return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET,
     4242                                                 false /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf);
     4243
     4244    /* ASSUME we're in the zero padding at the end of a path table. */
     4245    Assert(   offUnsigned - pFinalizedDirs->offPathTableL <  RT_ALIGN_32(pFinalizedDirs->cbPathTable, RTFSISOMAKER_SECTOR_SIZE)
     4246           || offUnsigned - pFinalizedDirs->offPathTableM <  RT_ALIGN_32(pFinalizedDirs->cbPathTable, RTFSISOMAKER_SECTOR_SIZE));
     4247    size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - ((size_t)offUnsigned & RTFSISOMAKER_SECTOR_OFFSET_MASK));
     4248    memset(pbBuf, 0, cbZeros);
     4249    return cbZeros;
    38964250}
    38974251
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