VirtualBox

Changeset 66767 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
May 4, 2017 12:46:42 AM (8 years ago)
Author:
vboxsync
Message:

iso9660: Rough ReadDir implementation. Also a build fix.

Location:
trunk/src/VBox/Runtime/common
Files:
2 edited

Legend:

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

    r66766 r66767  
    721721        {
    722722            uint32_t cRefs = ASMAtomicIncU32(&pCur->cRefs);
    723             Assert(cRefs > 1);
     723            Assert(cRefs > 1); RT_NOREF(cRefs);
    724724            return pCur;
    725725        }
     
    974974            {
    975975                case RTFS_TYPE_DIRECTORY:
    976                     rc = rtFsIso9660Dir_New(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
     976                    if (phVfsDir)
     977                        rc = rtFsIso9660Dir_New(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
     978                    else
     979                        rc = VERR_NOT_SYMLINK;
    977980                    break;
    978981
     
    10611064static DECLCALLBACK(int) rtFsIso9660Dir_OpenDir(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir)
    10621065{
    1063     RT_NOREF(pvThis, pszSubDir, fFlags, phVfsDir);
    1064 RTAssertMsg2("%s: %s\n", __FUNCTION__, pszSubDir);
    1065     return VERR_NOT_IMPLEMENTED;
     1066    PRTFSISO9660DIROBJ  pThis   = (PRTFSISO9660DIROBJ)pvThis;
     1067    PRTFSISO9660DIRSHRD pShared = pThis->pShared;
     1068    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
     1069
     1070    /*
     1071     * Try open file.
     1072     */
     1073    PCISO9660DIRREC pDirRec;
     1074    uint64_t        offDirRec;
     1075    uint32_t        cDirRecs;
     1076    RTFMODE         fMode;
     1077    int rc = rtFsIso9660Dir_FindEntry(pShared, pszSubDir, &offDirRec, &pDirRec, &cDirRecs, &fMode);
     1078    Log2(("rtFsIso9660Dir_OpenDir: FindEntry(,%s,) -> %Rrc\n", pszSubDir, rc));
     1079    if (RT_SUCCESS(rc))
     1080    {
     1081        switch (fMode & RTFS_TYPE_MASK)
     1082        {
     1083            case RTFS_TYPE_DIRECTORY:
     1084                rc = rtFsIso9660Dir_New(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
     1085                break;
     1086
     1087            case RTFS_TYPE_FILE:
     1088            case RTFS_TYPE_SYMLINK:
     1089            case RTFS_TYPE_DEV_BLOCK:
     1090            case RTFS_TYPE_DEV_CHAR:
     1091            case RTFS_TYPE_FIFO:
     1092            case RTFS_TYPE_SOCKET:
     1093            case RTFS_TYPE_WHITEOUT:
     1094                rc = VERR_NOT_A_DIRECTORY;
     1095                break;
     1096
     1097            default:
     1098                rc = VERR_PATH_NOT_FOUND;
     1099                break;
     1100        }
     1101    }
     1102    return rc;
    10661103}
    10671104
     
    11681205                                                RTFSOBJATTRADD enmAddAttr)
    11691206{
    1170     //PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis;
    1171     RT_NOREF(pvThis, pDirEntry, pcbDirEntry, enmAddAttr);
    1172     return VERR_NOT_IMPLEMENTED;
     1207    PRTFSISO9660DIROBJ  pThis   = (PRTFSISO9660DIROBJ)pvThis;
     1208    PRTFSISO9660DIRSHRD pShared = pThis->pShared;
     1209
     1210    while (pThis->offDir + RT_UOFFSETOF(ISO9660DIRREC, achFileId) <= pShared->cbDir)
     1211    {
     1212        PCISO9660DIRREC pDirRec = (PCISO9660DIRREC)&pShared->pbDir[pThis->offDir];
     1213
     1214        /* If null length, skip to the next sector. */
     1215        if (pDirRec->cbDirRec == 0)
     1216            pThis->offDir = (pThis->offDir + pShared->Core.pVol->cbSector) & ~(pShared->Core.pVol->cbSector - 1U);
     1217        else
     1218        {
     1219            /*
     1220             * Do names first as they may cause overflows.
     1221             */
     1222            if (   pDirRec->bFileIdLength == 1
     1223                && pDirRec->achFileId[0]  == '\0')
     1224            {
     1225                if (*pcbDirEntry < RT_OFFSETOF(RTDIRENTRYEX, szName) + 2)
     1226                {
     1227                    *pcbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + 2;
     1228                    return VERR_BUFFER_OVERFLOW;
     1229                }
     1230                pDirEntry->cbName    = 1;
     1231                pDirEntry->szName[0] = '.';
     1232                pDirEntry->szName[1] = '\0';
     1233            }
     1234            else if (   pDirRec->bFileIdLength == 1
     1235                     && pDirRec->achFileId[0]  == '\0')
     1236            {
     1237                if (*pcbDirEntry < RT_OFFSETOF(RTDIRENTRYEX, szName) + 3)
     1238                {
     1239                    *pcbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + 3;
     1240                    return VERR_BUFFER_OVERFLOW;
     1241                }
     1242                pDirEntry->cbName    = 2;
     1243                pDirEntry->szName[0] = '.';
     1244                pDirEntry->szName[1] = '.';
     1245                pDirEntry->szName[2] = '\0';
     1246            }
     1247            else if (pShared->Core.pVol->fIsUtf16)
     1248            {
     1249                /* UTF-16BE -> UTF-8 conversion is a bit tedious since we don't have the necessary IPRT APIs yet. */
     1250                PCRTUTF16 pwcSrc    = (PCRTUTF16)&pDirRec->achFileId[0];
     1251                PCRTUTF16 pwcSrcEnd = &pwcSrc[pDirRec->bFileIdLength / sizeof(RTUTF16)];
     1252                size_t    cbDst     = *pcbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName);
     1253                char     *pszDst    = pDirEntry->szName;
     1254                while ((uintptr_t)pwcSrc < (uintptr_t)pwcSrcEnd)
     1255                {
     1256                    RTUNICP uc;
     1257                    int rc = RTUtf16BigGetCpEx(&pwcSrc, &uc);
     1258                    if (RT_FAILURE(rc))
     1259                        uc = '?';
     1260                    size_t cchCp = RTStrCpSize(uc);
     1261                    if (cchCp < cbDst)
     1262                    {
     1263                        cbDst -= cchCp;
     1264                        pszDst = RTStrPutCp(pszDst, uc);
     1265                    }
     1266                    else
     1267                    {
     1268                        /* Buffer overflow.  Figure out how much we really need. */
     1269                        size_t off = pszDst - &pDirEntry->szName[0];
     1270                        off += cchCp;
     1271                        while ((uintptr_t)pwcSrc < (uintptr_t)pwcSrcEnd)
     1272                        {
     1273                            RTUtf16BigGetCpEx(&pwcSrc, &uc);
     1274                            off += RTStrCpSize(uc);
     1275                        }
     1276                        *pcbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + off + 1;
     1277                        return VERR_BUFFER_OVERFLOW;
     1278                    }
     1279                }
     1280                *pszDst = '\0';
     1281            }
     1282            else
     1283            {
     1284                /* This is supposed to be upper case ASCII, however, purge the encoding anyway. */
     1285                size_t cbNeeded = RT_OFFSETOF(RTDIRENTRYEX, szName) + pDirRec->bFileIdLength + 1;
     1286                if (*pcbDirEntry < cbNeeded)
     1287                {
     1288                    *pcbDirEntry = cbNeeded;
     1289                    return VERR_BUFFER_OVERFLOW;
     1290                }
     1291                pDirEntry->cbName = pDirRec->bFileIdLength;
     1292                memcpy(pDirEntry->szName, pDirRec->achFileId, pDirRec->bFileIdLength);
     1293                RTStrPurgeEncoding(pDirEntry->szName);
     1294
     1295                /** @todo check for rock ridge names here.   */
     1296            }
     1297            pDirEntry->cwcShortName    = 0;
     1298            pDirEntry->wszShortName[0] = '\0';
     1299
     1300            /*
     1301             * To avoid duplicating code in rtFsIso9660Core_InitFromDirRec and
     1302             * rtFsIso9660Core_QueryInfo, we create a dummy RTFSISO9660CORE on the stack.
     1303             */
     1304            RTFSISO9660CORE TmpObj;
     1305            RT_ZERO(TmpObj);
     1306            rtFsIso9660Core_InitFromDirRec(&TmpObj, pDirRec, 1/*cDirRecs*/, /** @todo multi-extent stuff */
     1307                                           pThis->offDir + pShared->Core.FirstExtent.offDisk, pShared->Core.pVol);
     1308            int rc = rtFsIso9660Core_QueryInfo(&TmpObj, &pDirEntry->Info, enmAddAttr);
     1309
     1310            /*
     1311             * Update the location and return.
     1312             */
     1313            pThis->offDir += pDirRec->cbDirRec;
     1314            return rc;
     1315        }
     1316    }
     1317
     1318    return VERR_NO_MORE_FILES;
    11731319}
    11741320
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r66762 r66767  
    14891489            *pszEntryEnd = '\0';
    14901490            if (   rc == VERR_PATH_NOT_FOUND
    1491                 || rc == VERR_NOT_A_DIRECTORY)
     1491                || rc == VERR_NOT_A_DIRECTORY
     1492                || rc == VERR_NOT_SYMLINK)
    14921493                rc = VINF_SUCCESS;
    14931494            if (RT_FAILURE(rc))
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