VirtualBox

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


Ignore:
Timestamp:
Apr 25, 2017 9:16:31 AM (8 years ago)
Author:
vboxsync
Message:

fatvfs: Implemented reading files.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp

    r66669 r66670  
    137137    /** The current file offset. */
    138138    uint32_t        offFile;
     139    /** Set if we've maybe dirtied the FAT. */
     140    bool            fMaybeDirtyFat;
     141    /** Set if we've maybe dirtied the directory entry. */
     142    bool            fMaybeDirtyDirEnt;
    139143} RTFSFATFILE;
    140144typedef RTFSFATFILE *PRTFSFATFILE;
     
    413417static void rtFsFatDir_AddOpenChild(PRTFSFATDIR pDir, PRTFSFATOBJ pChild);
    414418static void rtFsFatDir_RemoveOpenChild(PRTFSFATDIR pDir, PRTFSFATOBJ pChild);
     419static int  rtFsFatDir_Flush(PRTFSFATDIR pThis);
    415420static int  rtFsFatDir_New(PRTFSFATVOL pThis, PRTFSFATDIR pParentDir, PCFATDIRENTRY pDirEntry, uint32_t offEntryInDir,
    416421                           uint32_t idxCluster, uint64_t offDisk, uint32_t cbDir, PRTVFSDIR phVfsDir, PRTFSFATDIR *ppDir);
     
    484489 * @param   pChain              The chain.
    485490 * @param   offFile             The file offset.
    486  */
    487 static uint64_t rtFsFatChain_FileOffsetToDiskOff(PCRTFSFATCHAIN pChain, uint32_t offFile)
     491 * @param   pVol                The volume.
     492 */
     493static uint64_t rtFsFatChain_FileOffsetToDiskOff(PCRTFSFATCHAIN pChain, uint32_t offFile, PCRTFSFATVOL pVol)
    488494{
    489495    uint32_t idxCluster = offFile >> pChain->cClusterByteShift;
     
    496502            pPart = RTListGetNext(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry);
    497503        }
    498         return pPart->aEntries[idxCluster] + (offFile & ~(pChain->cbCluster - 1));
     504        return pVol->offFirstCluster
     505             + ((uint64_t)(pPart->aEntries[idxCluster] - FAT_FIRST_DATA_CLUSTER) << pChain->cClusterByteShift)
     506             + (offFile & (pChain->cbCluster - 1));
    499507    }
    500508    return UINT64_MAX;
     
    737745
    738746
     747#if 0 /* unused */
    739748/**
    740749 * Flushes out all dirty lines in the file allocation table (cluster map) cache.
     
    750759    return rtFsFatClusterMap_FlushWorker(pThis, iEntry, iEntry);
    751760}
     761#endif
    752762
    753763
     
    802812    {
    803813        /* Validate the cluster, checking for end of file. */
    804 RTAssertMsg2("idxCluster=%#x cClusters=%#x\n", idxCluster, pVol->cClusters);
    805814        if (   idxCluster >= pVol->cClusters
    806815            || idxCluster <  FAT_FIRST_DATA_CLUSTER)
     
    818827        /* Next cluster. */
    819828        bool     fOdd   = idxCluster & 1;
    820         uint32_t offFat = idxCluster * 2 / 3;
     829        uint32_t offFat = idxCluster * 3 / 2;
    821830        idxCluster = RT_MAKE_U16(pbFat[offFat], pbFat[offFat + 1]);
    822831        if (fOdd)
     
    10431052{
    10441053    PRTFSFATFILE pThis = (PRTFSFATFILE)pvThis;
    1045     RT_NOREF(pThis, off, pSgBuf, fBlocking, pcbRead);
    1046     return VERR_NOT_IMPLEMENTED;
     1054    AssertReturn(pSgBuf->cSegs != 0, VERR_INTERNAL_ERROR_3);
     1055    RT_NOREF(fBlocking);
     1056
     1057    /*
     1058     * Check for EOF.
     1059     */
     1060    if (off == -1)
     1061        off = pThis->offFile;
     1062    if ((uint64_t)off >= pThis->Core.cbObject)
     1063    {
     1064        if (pcbRead)
     1065        {
     1066            *pcbRead = 0;
     1067            return VINF_EOF;
     1068        }
     1069        return VERR_EOF;
     1070    }
     1071
     1072    /*
     1073     * Do the reading cluster by cluster (converge clusters later).
     1074     */
     1075    int      rc         = VINF_SUCCESS;
     1076    uint32_t cbFileLeft = pThis->Core.cbObject - (uint32_t)off;
     1077    uint32_t cbRead     = 0;
     1078    uint32_t cbLeft     = pSgBuf->paSegs[0].cbSeg;
     1079    uint8_t *pbDst      = (uint8_t *)pSgBuf->paSegs[0].pvSeg;
     1080    while (cbLeft > 0)
     1081    {
     1082        if (cbFileLeft > 0)
     1083        {
     1084            uint64_t offDisk = rtFsFatChain_FileOffsetToDiskOff(&pThis->Core.Clusters, (uint32_t)off, pThis->Core.pVol);
     1085            if (offDisk != UINT64_MAX)
     1086            {
     1087                uint32_t cbToRead = pThis->Core.Clusters.cbCluster - ((uint32_t)off & (pThis->Core.Clusters.cbCluster - 1));
     1088                if (cbToRead > cbLeft)
     1089                    cbToRead = cbLeft;
     1090                if (cbToRead > cbFileLeft)
     1091                    cbToRead = cbFileLeft;
     1092                rc = RTVfsFileReadAt(pThis->Core.pVol->hVfsBacking, offDisk, pbDst, cbToRead, NULL);
     1093                if (RT_SUCCESS(rc))
     1094                {
     1095                    off         += cbToRead;
     1096                    pbDst       += cbToRead;
     1097                    cbRead      += cbToRead;
     1098                    cbFileLeft  -= cbToRead;
     1099                    cbLeft      -= cbToRead;
     1100                    continue;
     1101                }
     1102            }
     1103            else
     1104                rc = VERR_VFS_BOGUS_OFFSET;
     1105        }
     1106        else
     1107            rc = pcbRead ? VINF_EOF : VERR_EOF;
     1108        break;
     1109    }
     1110    pThis->offFile = off;
     1111    if (pcbRead)
     1112        *pcbRead = cbRead;
     1113    return VINF_SUCCESS;
    10471114}
    10481115
     
    10651132{
    10661133    PRTFSFATFILE pThis = (PRTFSFATFILE)pvThis;
    1067     RT_NOREF(pThis);
    1068     return VERR_NOT_IMPLEMENTED;
     1134    int rc = VINF_SUCCESS;
     1135    if (pThis->fMaybeDirtyFat)
     1136        rc = rtFsFatClusterMap_Flush(pThis->Core.pVol);
     1137    if (pThis->fMaybeDirtyDirEnt)
     1138    {
     1139        int rc2 = rtFsFatDir_Flush(pThis->Core.pParentDir);
     1140        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     1141            rc = rc2;
     1142    }
     1143
     1144    int rc2 = RTVfsFileFlush(pThis->Core.pVol->hVfsBacking);
     1145    if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     1146        rc = rc2;
     1147    return rc;
    10691148}
    10701149
     
    12151294        },
    12161295        RTVFSIOSTREAMOPS_VERSION,
    1217         0,
     1296        RTVFSIOSTREAMOPS_FEAT_NO_SG,
    12181297        rtFsFatFile_Read,
    12191298        rtFsFatFile_Write,
     
    12681347         */
    12691348        rtFsFatObj_InitFromDirEntry(&pNewFile->Core, pDirEntry, offEntryInDir, pThis);
    1270         pNewFile->offFile = 0;
     1349        pNewFile->offFile           = 0;
     1350        pNewFile->fMaybeDirtyFat    = false;
     1351        pNewFile->fMaybeDirtyDirEnt = false;
    12711352        rc = rtFsFatClusterMap_ReadClusterChain(pThis, RTFSFAT_GET_CLUSTER(pDirEntry, pThis), &pNewFile->Core.Clusters);
    12721353        if (RT_SUCCESS(rc))
     
    13931474                    off                      =  offEntryInDir &  (pVol->cbSector - 1);
    13941475                    pThis->u.Simple.offInDir = (offEntryInDir & ~(pVol->cbSector - 1));
    1395                     pThis->offEntriesOnDisk  = rtFsFatChain_FileOffsetToDiskOff(&pThis->Core.Clusters, pThis->u.Simple.offInDir);
     1476                    pThis->offEntriesOnDisk  = rtFsFatChain_FileOffsetToDiskOff(&pThis->Core.Clusters, pThis->u.Simple.offInDir,
     1477                                                                                pThis->Core.pVol);
    13961478                    rc = RTVfsFileReadAt(pThis->Core.pVol->hVfsBacking, pThis->offEntriesOnDisk,
    13971479                                         pThis->paEntries, pVol->cbSector, NULL);
     
    15151597                    pszName8Dot3[offDst] = '\0';
    15161598
    1517                     if (pszName8Dot3[0] == FATDIRENTRY_CH0_DELETED)
     1599                    if ((uint8_t)pszName8Dot3[0] == FATDIRENTRY_CH0_DELETED)
    15181600                        pszName8Dot3[0] = FATDIRENTRY_CH0_ESC_E5;
    15191601                    return true;
     
    15751657        for (uint32_t iEntry = 0; iEntry < cEntries; iEntry++, offEntryInDir += sizeof(FATDIRENTRY))
    15761658        {
    1577             switch (paEntries[iEntry].Entry.achName[0])
     1659            switch ((uint8_t)paEntries[iEntry].Entry.achName[0])
    15781660            {
    15791661                default:
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