Changeset 66670 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Apr 25, 2017 9:16:31 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp
r66669 r66670 137 137 /** The current file offset. */ 138 138 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; 139 143 } RTFSFATFILE; 140 144 typedef RTFSFATFILE *PRTFSFATFILE; … … 413 417 static void rtFsFatDir_AddOpenChild(PRTFSFATDIR pDir, PRTFSFATOBJ pChild); 414 418 static void rtFsFatDir_RemoveOpenChild(PRTFSFATDIR pDir, PRTFSFATOBJ pChild); 419 static int rtFsFatDir_Flush(PRTFSFATDIR pThis); 415 420 static int rtFsFatDir_New(PRTFSFATVOL pThis, PRTFSFATDIR pParentDir, PCFATDIRENTRY pDirEntry, uint32_t offEntryInDir, 416 421 uint32_t idxCluster, uint64_t offDisk, uint32_t cbDir, PRTVFSDIR phVfsDir, PRTFSFATDIR *ppDir); … … 484 489 * @param pChain The chain. 485 490 * @param offFile The file offset. 486 */ 487 static uint64_t rtFsFatChain_FileOffsetToDiskOff(PCRTFSFATCHAIN pChain, uint32_t offFile) 491 * @param pVol The volume. 492 */ 493 static uint64_t rtFsFatChain_FileOffsetToDiskOff(PCRTFSFATCHAIN pChain, uint32_t offFile, PCRTFSFATVOL pVol) 488 494 { 489 495 uint32_t idxCluster = offFile >> pChain->cClusterByteShift; … … 496 502 pPart = RTListGetNext(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry); 497 503 } 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)); 499 507 } 500 508 return UINT64_MAX; … … 737 745 738 746 747 #if 0 /* unused */ 739 748 /** 740 749 * Flushes out all dirty lines in the file allocation table (cluster map) cache. … … 750 759 return rtFsFatClusterMap_FlushWorker(pThis, iEntry, iEntry); 751 760 } 761 #endif 752 762 753 763 … … 802 812 { 803 813 /* Validate the cluster, checking for end of file. */ 804 RTAssertMsg2("idxCluster=%#x cClusters=%#x\n", idxCluster, pVol->cClusters);805 814 if ( idxCluster >= pVol->cClusters 806 815 || idxCluster < FAT_FIRST_DATA_CLUSTER) … … 818 827 /* Next cluster. */ 819 828 bool fOdd = idxCluster & 1; 820 uint32_t offFat = idxCluster * 2 / 3;829 uint32_t offFat = idxCluster * 3 / 2; 821 830 idxCluster = RT_MAKE_U16(pbFat[offFat], pbFat[offFat + 1]); 822 831 if (fOdd) … … 1043 1052 { 1044 1053 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; 1047 1114 } 1048 1115 … … 1065 1132 { 1066 1133 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; 1069 1148 } 1070 1149 … … 1215 1294 }, 1216 1295 RTVFSIOSTREAMOPS_VERSION, 1217 0,1296 RTVFSIOSTREAMOPS_FEAT_NO_SG, 1218 1297 rtFsFatFile_Read, 1219 1298 rtFsFatFile_Write, … … 1268 1347 */ 1269 1348 rtFsFatObj_InitFromDirEntry(&pNewFile->Core, pDirEntry, offEntryInDir, pThis); 1270 pNewFile->offFile = 0; 1349 pNewFile->offFile = 0; 1350 pNewFile->fMaybeDirtyFat = false; 1351 pNewFile->fMaybeDirtyDirEnt = false; 1271 1352 rc = rtFsFatClusterMap_ReadClusterChain(pThis, RTFSFAT_GET_CLUSTER(pDirEntry, pThis), &pNewFile->Core.Clusters); 1272 1353 if (RT_SUCCESS(rc)) … … 1393 1474 off = offEntryInDir & (pVol->cbSector - 1); 1394 1475 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); 1396 1478 rc = RTVfsFileReadAt(pThis->Core.pVol->hVfsBacking, pThis->offEntriesOnDisk, 1397 1479 pThis->paEntries, pVol->cbSector, NULL); … … 1515 1597 pszName8Dot3[offDst] = '\0'; 1516 1598 1517 if ( pszName8Dot3[0] == FATDIRENTRY_CH0_DELETED)1599 if ((uint8_t)pszName8Dot3[0] == FATDIRENTRY_CH0_DELETED) 1518 1600 pszName8Dot3[0] = FATDIRENTRY_CH0_ESC_E5; 1519 1601 return true; … … 1575 1657 for (uint32_t iEntry = 0; iEntry < cEntries; iEntry++, offEntryInDir += sizeof(FATDIRENTRY)) 1576 1658 { 1577 switch ( paEntries[iEntry].Entry.achName[0])1659 switch ((uint8_t)paEntries[iEntry].Entry.achName[0]) 1578 1660 { 1579 1661 default:
Note:
See TracChangeset
for help on using the changeset viewer.