- Timestamp:
- Nov 12, 2017 4:17:36 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
r69660 r69663 311 311 /** The FAT size. */ 312 312 uint32_t cbFat; 313 /** The Number of clusters in the FAT. */ 314 uint32_t cClusters; 313 315 /** Cluster allocation search hint. */ 314 316 uint32_t idxAllocHint; … … 821 823 * Allocate and initialize it all. 822 824 */ 823 PRTFSFATCLUSTERMAPCACHE p Cache;824 pThis->pFatCache = p Cache = (PRTFSFATCLUSTERMAPCACHE)RTMemAllocZ(RT_OFFSETOF(RTFSFATCLUSTERMAPCACHE, aEntries[cEntries]));825 if (!p Cache)825 PRTFSFATCLUSTERMAPCACHE pFatCache; 826 pThis->pFatCache = pFatCache = (PRTFSFATCLUSTERMAPCACHE)RTMemAllocZ(RT_OFFSETOF(RTFSFATCLUSTERMAPCACHE, aEntries[cEntries])); 827 if (!pFatCache) 826 828 return RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "Failed to allocate FAT cache"); 827 pCache->cEntries = cEntries; 828 pCache->fEntryIndexMask = fEntryIndexMask; 829 pCache->cEntryIndexShift = cEntryIndexShift; 830 pCache->cbEntry = cbEntry; 831 pCache->fEntryOffsetMask = fEntryOffsetMask; 832 pCache->pVol = pThis; 833 pCache->cbFat = pThis->cbFat; 829 pFatCache->cEntries = cEntries; 830 pFatCache->fEntryIndexMask = fEntryIndexMask; 831 pFatCache->cEntryIndexShift = cEntryIndexShift; 832 pFatCache->cbEntry = cbEntry; 833 pFatCache->fEntryOffsetMask = fEntryOffsetMask; 834 pFatCache->pVol = pThis; 835 pFatCache->cbFat = pThis->cbFat; 836 pFatCache->cClusters = pThis->cClusters; 834 837 835 838 unsigned i = cEntries; 836 839 while (i-- > 0) 837 840 { 838 p Cache->aEntries[i].pbData = (uint8_t *)RTMemAlloc(cbEntry);839 if (p Cache->aEntries[i].pbData == NULL)841 pFatCache->aEntries[i].pbData = (uint8_t *)RTMemAlloc(cbEntry); 842 if (pFatCache->aEntries[i].pbData == NULL) 840 843 { 841 844 for (i++; i < cEntries; i++) 842 RTMemFree(p Cache->aEntries[i].pbData);843 RTMemFree(p Cache);845 RTMemFree(pFatCache->aEntries[i].pbData); 846 RTMemFree(pFatCache); 844 847 return RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "Failed to allocate FAT cache entry (%#x bytes)", cbEntry); 845 848 } 846 849 847 p Cache->aEntries[i].offFat = UINT32_MAX;848 p Cache->aEntries[i].bmDirty = 0;850 pFatCache->aEntries[i].offFat = UINT32_MAX; 851 pFatCache->aEntries[i].bmDirty = 0; 849 852 } 850 853 Log3(("rtFsFatClusterMap_Create: cbFat=%#RX32 cEntries=%RU32 cEntryIndexShift=%RU32 fEntryIndexMask=%#RX32\n", 851 p Cache->cbFat, pCache->cEntries, pCache->cEntryIndexShift, pCache->fEntryIndexMask));852 Log3(("rtFsFatClusterMap_Create: cbEntries=%#RX32 fEntryOffsetMask=%#RX32\n", p Cache->cbEntry, pCache->fEntryOffsetMask));854 pFatCache->cbFat, pFatCache->cEntries, pFatCache->cEntryIndexShift, pFatCache->fEntryIndexMask)); 855 Log3(("rtFsFatClusterMap_Create: cbEntries=%#RX32 fEntryOffsetMask=%#RX32\n", pFatCache->cbEntry, pFatCache->fEntryOffsetMask)); 853 856 854 857 /* … … 859 862 cbEntry = pThis->cbSector; 860 863 861 p Cache->cDirtyShift = 1;862 p Cache->cbDirtyLine = 1;863 while (p Cache->cbDirtyLine < cbEntry)864 { 865 p Cache->cDirtyShift++;866 p Cache->cbDirtyLine <<= 1;867 } 868 Assert(p Cache->cEntries == 1 || pCache->cbDirtyLine == pThis->cbSector);869 Log3(("rtFsFatClusterMap_Create: cbDirtyLine=%#RX32 cDirtyShift=%u\n", p Cache->cbDirtyLine, pCache->cDirtyShift));864 pFatCache->cDirtyShift = 1; 865 pFatCache->cbDirtyLine = 1; 866 while (pFatCache->cbDirtyLine < cbEntry) 867 { 868 pFatCache->cDirtyShift++; 869 pFatCache->cbDirtyLine <<= 1; 870 } 871 Assert(pFatCache->cEntries == 1 || pFatCache->cbDirtyLine == pThis->cbSector); 872 Log3(("rtFsFatClusterMap_Create: cbDirtyLine=%#RX32 cDirtyShift=%u\n", pFatCache->cbDirtyLine, pFatCache->cDirtyShift)); 870 873 871 874 /* 872 875 * Fill the cache if single entry or entry size is 512. 873 876 */ 874 if (p Cache->cEntries == 1 || pCache->cbEntry == 512)875 { 876 memcpy(p Cache->aEntries[0].pbData, pbFirst512FatBytes, RT_MIN(512, pCache->cbEntry));877 if (p Cache->cbEntry > 512)877 if (pFatCache->cEntries == 1 || pFatCache->cbEntry == 512) 878 { 879 memcpy(pFatCache->aEntries[0].pbData, pbFirst512FatBytes, RT_MIN(512, pFatCache->cbEntry)); 880 if (pFatCache->cbEntry > 512) 878 881 { 879 882 int rc = RTVfsFileReadAt(pThis->hVfsBacking, pThis->aoffFats[0] + 512, 880 &p Cache->aEntries[0].pbData[512], pCache->cbEntry - 512, NULL);883 &pFatCache->aEntries[0].pbData[512], pFatCache->cbEntry - 512, NULL); 881 884 if (RT_FAILURE(rc)) 882 885 return RTErrInfoSet(pErrInfo, rc, "Error reading FAT into memory"); 883 886 } 884 p Cache->aEntries[0].offFat = 0;885 p Cache->aEntries[0].bmDirty = 0;887 pFatCache->aEntries[0].offFat = 0; 888 pFatCache->aEntries[0].bmDirty = 0; 886 889 } 887 890 … … 900 903 static int rtFsFatClusterMap_FlushWorker(PRTFSFATVOL pThis, uint32_t const iFirstEntry, uint32_t const iLastEntry) 901 904 { 902 PRTFSFATCLUSTERMAPCACHE pCache = pThis->pFatCache; 903 905 PRTFSFATCLUSTERMAPCACHE pFatCache = pThis->pFatCache; 904 906 905 907 /* … … 918 920 for (uint32_t iEntry = iFirstEntry; iEntry <= iLastEntry; iEntry++) 919 921 { 920 uint64_t bmDirty = p Cache->aEntries[iEntry].bmDirty;922 uint64_t bmDirty = pFatCache->aEntries[iEntry].bmDirty; 921 923 if ( bmDirty != 0 922 && p Cache->aEntries[iEntry].offFat != UINT32_MAX)924 && pFatCache->aEntries[iEntry].offFat != UINT32_MAX) 923 925 { 924 926 uint32_t offEntry = 0; 925 927 uint64_t iDirtyLine = 1; 926 while (offEntry < p Cache->cbEntry)928 while (offEntry < pFatCache->cbEntry) 927 929 { 928 if (p Cache->aEntries[iEntry].bmDirty & iDirtyLine)930 if (pFatCache->aEntries[iEntry].bmDirty & iDirtyLine) 929 931 { 930 932 /* 931 933 * Found dirty cache line. 932 934 */ 933 uint64_t offDirtyLine = pThis->aoffFats[iFatCopy] + p Cache->aEntries[iEntry].offFat + offEntry;935 uint64_t offDirtyLine = pThis->aoffFats[iFatCopy] + pFatCache->aEntries[iEntry].offFat + offEntry; 934 936 935 937 /* Can we simply extend the last segment? */ … … 939 941 Assert(SgBuf.cSegs > 0); 940 942 Assert( (uintptr_t)aSgSegs[SgBuf.cSegs - 1].pvSeg + aSgSegs[SgBuf.cSegs - 1].cbSeg 941 == (uintptr_t)&p Cache->aEntries[iEntry].pbData[offEntry]);942 aSgSegs[SgBuf.cSegs - 1].cbSeg += p Cache->cbDirtyLine;943 offEdge += p Cache->cbDirtyLine;943 == (uintptr_t)&pFatCache->aEntries[iEntry].pbData[offEntry]); 944 aSgSegs[SgBuf.cSegs - 1].cbSeg += pFatCache->cbDirtyLine; 945 offEdge += pFatCache->cbDirtyLine; 944 946 } 945 947 else … … 964 966 965 967 /* Append segment. */ 966 aSgSegs[SgBuf.cSegs].cbSeg = p Cache->cbDirtyLine;967 aSgSegs[SgBuf.cSegs].pvSeg = &p Cache->aEntries[iEntry].pbData[offEntry];968 aSgSegs[SgBuf.cSegs].cbSeg = pFatCache->cbDirtyLine; 969 aSgSegs[SgBuf.cSegs].pvSeg = &pFatCache->aEntries[iEntry].pbData[offEntry]; 968 970 SgBuf.cSegs++; 969 offEdge = offDirtyLine + p Cache->cbDirtyLine;971 offEdge = offDirtyLine + pFatCache->cbDirtyLine; 970 972 } 971 973 … … 975 977 } 976 978 iDirtyLine <<= 1; 977 offEntry += p Cache->cbDirtyLine;979 offEntry += pFatCache->cbDirtyLine; 978 980 } 979 981 Assert(!bmDirty); … … 997 999 if (RT_SUCCESS(rc)) 998 1000 for (uint32_t iEntry = iFirstEntry; iEntry <= iLastEntry; iEntry++) 999 p Cache->aEntries[iEntry].bmDirty = 0;1001 pFatCache->aEntries[iEntry].bmDirty = 0; 1000 1002 1001 1003 return rc; … … 1022 1024 * 1023 1025 * @returns IPRT status code. On failure, we're currently kind of screwed. 1024 * @param p This The FAT volume instance.1026 * @param pFatCache The FAT cache 1025 1027 * @param iEntry The cache entry to flush. 1026 1028 */ 1027 static int rtFsFatClusterMap_FlushEntry(PRTFSFAT VOL pThis, uint32_t iEntry)1028 { 1029 return rtFsFatClusterMap_FlushWorker(p This, iEntry, iEntry);1029 static int rtFsFatClusterMap_FlushEntry(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t iEntry) 1030 { 1031 return rtFsFatClusterMap_FlushWorker(pFatCache->pVol, iEntry, iEntry); 1030 1032 } 1031 1033 … … 1035 1037 * 1036 1038 * @returns IPRT status code. On failure, we're currently kind of screwed. 1037 * @param pCache The FAT cache. 1038 * @param pThis The FAT volume instance. 1039 * @param offFat The FAT byte offset to get the entry off. 1040 * @param ppbEntry Where to return the pointer to the entry. 1041 */ 1042 static int rtFsFatClusterMap_GetEntry(PRTFSFATCLUSTERMAPCACHE pCache, PRTFSFATVOL pThis, uint32_t offFat, uint8_t **ppbEntry) 1039 * @param pFatCache The FAT cache. 1040 * @param offFat The FAT byte offset to get the entry off. 1041 * @param ppbEntry Where to return the pointer to the entry. 1042 */ 1043 static int rtFsFatClusterMap_GetEntry(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t offFat, uint8_t **ppbEntry) 1043 1044 { 1044 1045 int rc; 1045 if (offFat < p This->cbFat)1046 { 1047 uint32_t const iEntry = (offFat >> p Cache->cEntryIndexShift) & pCache->fEntryIndexMask;1048 uint32_t const offInEntry = offFat & p Cache->fEntryOffsetMask;1046 if (offFat < pFatCache->cbFat) 1047 { 1048 uint32_t const iEntry = (offFat >> pFatCache->cEntryIndexShift) & pFatCache->fEntryIndexMask; 1049 uint32_t const offInEntry = offFat & pFatCache->fEntryOffsetMask; 1049 1050 uint32_t const offFatEntry = offFat - offInEntry; 1050 1051 1051 *ppbEntry = p Cache->aEntries[iEntry].pbData + offInEntry;1052 *ppbEntry = pFatCache->aEntries[iEntry].pbData + offInEntry; 1052 1053 1053 1054 /* If it's already ready, return immediately. */ 1054 if (p Cache->aEntries[iEntry].offFat == offFatEntry)1055 if (pFatCache->aEntries[iEntry].offFat == offFatEntry) 1055 1056 { 1056 1057 Log3(("rtFsFatClusterMap_GetEntry: Hit entry %u for offFat=%#RX32\n", iEntry, offFat)); … … 1060 1061 /* Do we need to flush it? */ 1061 1062 rc = VINF_SUCCESS; 1062 if ( p Cache->aEntries[iEntry].bmDirty != 01063 && p Cache->aEntries[iEntry].offFat != UINT32_MAX)1063 if ( pFatCache->aEntries[iEntry].bmDirty != 0 1064 && pFatCache->aEntries[iEntry].offFat != UINT32_MAX) 1064 1065 { 1065 1066 Log3(("rtFsFatClusterMap_GetEntry: Flushing entry %u for offFat=%#RX32\n", iEntry, offFat)); 1066 rc = rtFsFatClusterMap_FlushEntry(p This, iEntry);1067 rc = rtFsFatClusterMap_FlushEntry(pFatCache, iEntry); 1067 1068 } 1068 1069 if (RT_SUCCESS(rc)) 1069 1070 { 1070 p Cache->aEntries[iEntry].bmDirty = 0;1071 pFatCache->aEntries[iEntry].bmDirty = 0; 1071 1072 1072 1073 /* Read in the entry from disk */ 1073 rc = RTVfsFileReadAt(p This->hVfsBacking, pThis->aoffFats[0] + offFatEntry, pCache->aEntries[iEntry].pbData,1074 p Cache->cbEntry, NULL);1074 rc = RTVfsFileReadAt(pFatCache->pVol->hVfsBacking, pFatCache->pVol->aoffFats[0] + offFatEntry, 1075 pFatCache->aEntries[iEntry].pbData, pFatCache->cbEntry, NULL); 1075 1076 if (RT_SUCCESS(rc)) 1076 1077 { 1077 1078 Log3(("rtFsFatClusterMap_GetEntry: Loaded entry %u for offFat=%#RX32\n", iEntry, offFat)); 1078 p Cache->aEntries[iEntry].offFat = offFatEntry;1079 pFatCache->aEntries[iEntry].offFat = offFatEntry; 1079 1080 return VINF_SUCCESS; 1080 1081 } 1081 1082 /** @todo We can try other FAT copies here... */ 1082 1083 LogRel(("rtFsFatClusterMap_GetEntry: Error loading entry %u for offFat=%#RX32 (%#64RX32 LB %#x): %Rrc\n", 1083 iEntry, offFat, p This->aoffFats[0] + offFatEntry, pCache->cbEntry, rc));1084 p Cache->aEntries[iEntry].offFat = UINT32_MAX;1084 iEntry, offFat, pFatCache->pVol->aoffFats[0] + offFatEntry, pFatCache->cbEntry, rc)); 1085 pFatCache->aEntries[iEntry].offFat = UINT32_MAX; 1085 1086 } 1086 1087 } … … 1096 1097 * 1097 1098 * @returns IPRT status code. On failure, we're currently kind of screwed. 1098 * @param pCache The FAT cache. 1099 * @param pThis The FAT volume instance. 1100 * @param offFat The FAT byte offset to get the entry off. 1101 * @param ppbEntry Where to return the pointer to the entry. 1102 * @param pidxEntry Where to return the entry index. 1103 */ 1104 static int rtFsFatClusterMap_GetEntryEx(PRTFSFATCLUSTERMAPCACHE pCache, PRTFSFATVOL pThis, uint32_t offFat, 1099 * @param pFatCache The FAT cache. 1100 * @param offFat The FAT byte offset to get the entry off. 1101 * @param ppbEntry Where to return the pointer to the entry. 1102 * @param pidxEntry Where to return the entry index. 1103 */ 1104 static int rtFsFatClusterMap_GetEntryEx(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t offFat, 1105 1105 uint8_t **ppbEntry, uint32_t *pidxEntry) 1106 1106 { 1107 1107 int rc; 1108 if (offFat < p This->cbFat)1109 { 1110 uint32_t const iEntry = (offFat >> p Cache->cEntryIndexShift) & pCache->fEntryIndexMask;1111 uint32_t const offInEntry = offFat & p Cache->fEntryOffsetMask;1108 if (offFat < pFatCache->cbFat) 1109 { 1110 uint32_t const iEntry = (offFat >> pFatCache->cEntryIndexShift) & pFatCache->fEntryIndexMask; 1111 uint32_t const offInEntry = offFat & pFatCache->fEntryOffsetMask; 1112 1112 uint32_t const offFatEntry = offFat - offInEntry; 1113 1113 1114 *ppbEntry = p Cache->aEntries[iEntry].pbData + offInEntry;1114 *ppbEntry = pFatCache->aEntries[iEntry].pbData + offInEntry; 1115 1115 *pidxEntry = iEntry; 1116 1116 1117 1117 /* If it's already ready, return immediately. */ 1118 if (p Cache->aEntries[iEntry].offFat == offFatEntry)1118 if (pFatCache->aEntries[iEntry].offFat == offFatEntry) 1119 1119 { 1120 1120 Log3(("rtFsFatClusterMap_GetEntryEx: Hit entry %u for offFat=%#RX32\n", iEntry, offFat)); … … 1124 1124 /* Do we need to flush it? */ 1125 1125 rc = VINF_SUCCESS; 1126 if ( p Cache->aEntries[iEntry].bmDirty != 01127 && p Cache->aEntries[iEntry].offFat != UINT32_MAX)1126 if ( pFatCache->aEntries[iEntry].bmDirty != 0 1127 && pFatCache->aEntries[iEntry].offFat != UINT32_MAX) 1128 1128 { 1129 1129 Log3(("rtFsFatClusterMap_GetEntryEx: Flushing entry %u for offFat=%#RX32\n", iEntry, offFat)); 1130 rc = rtFsFatClusterMap_FlushEntry(p This, iEntry);1130 rc = rtFsFatClusterMap_FlushEntry(pFatCache, iEntry); 1131 1131 } 1132 1132 if (RT_SUCCESS(rc)) 1133 1133 { 1134 p Cache->aEntries[iEntry].bmDirty = 0;1134 pFatCache->aEntries[iEntry].bmDirty = 0; 1135 1135 1136 1136 /* Read in the entry from disk */ 1137 rc = RTVfsFileReadAt(p This->hVfsBacking, pThis->aoffFats[0] + offFatEntry, pCache->aEntries[iEntry].pbData,1138 p Cache->cbEntry, NULL);1137 rc = RTVfsFileReadAt(pFatCache->pVol->hVfsBacking, pFatCache->pVol->aoffFats[0] + offFatEntry, 1138 pFatCache->aEntries[iEntry].pbData, pFatCache->cbEntry, NULL); 1139 1139 if (RT_SUCCESS(rc)) 1140 1140 { 1141 1141 Log3(("rtFsFatClusterMap_GetEntryEx: Loaded entry %u for offFat=%#RX32\n", iEntry, offFat)); 1142 p Cache->aEntries[iEntry].offFat = offFatEntry;1142 pFatCache->aEntries[iEntry].offFat = offFatEntry; 1143 1143 return VINF_SUCCESS; 1144 1144 } 1145 1145 /** @todo We can try other FAT copies here... */ 1146 1146 LogRel(("rtFsFatClusterMap_GetEntryEx: Error loading entry %u for offFat=%#RX32 (%#64RX32 LB %#x): %Rrc\n", 1147 iEntry, offFat, p This->aoffFats[0] + offFatEntry, pCache->cbEntry, rc));1148 p Cache->aEntries[iEntry].offFat = UINT32_MAX;1147 iEntry, offFat, pFatCache->pVol->aoffFats[0] + offFatEntry, pFatCache->cbEntry, rc)); 1148 pFatCache->aEntries[iEntry].offFat = UINT32_MAX; 1149 1149 } 1150 1150 } … … 1167 1167 static int rtFsFatClusterMap_Destroy(PRTFSFATVOL pThis) 1168 1168 { 1169 int rc = VINF_SUCCESS;1170 PRTFSFATCLUSTERMAPCACHE p Cache = pThis->pFatCache;1171 if (p Cache)1169 int rc = VINF_SUCCESS; 1170 PRTFSFATCLUSTERMAPCACHE pFatCache = pThis->pFatCache; 1171 if (pFatCache) 1172 1172 { 1173 1173 /* flush stuff. */ … … 1175 1175 1176 1176 /* free everything. */ 1177 uint32_t i = p Cache->cEntries;1177 uint32_t i = pFatCache->cEntries; 1178 1178 while (i-- > 0) 1179 1179 { 1180 RTMemFree(p Cache->aEntries[i].pbData);1181 p Cache->aEntries[i].pbData = NULL;1182 } 1183 p Cache->cEntries = 0;1184 RTMemFree(p Cache);1180 RTMemFree(pFatCache->aEntries[i].pbData); 1181 pFatCache->aEntries[i].pbData = NULL; 1182 } 1183 pFatCache->cEntries = 0; 1184 RTMemFree(pFatCache); 1185 1185 1186 1186 pThis->pFatCache = NULL; … … 1194 1194 * Worker for rtFsFatClusterMap_ReadClusterChain handling FAT12. 1195 1195 */ 1196 static int rtFsFatClusterMap_Fat12_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, uint32_t idxCluster, 1197 PRTFSFATCHAIN pChain) 1196 static int rtFsFatClusterMap_Fat12_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, PRTFSFATCHAIN pChain) 1198 1197 { 1199 1198 /* ASSUME that for FAT12 we cache the whole FAT in a single entry. That 1200 1199 way we don't need to deal with entries in different sectors and whatnot. */ 1201 1200 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1202 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1201 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1203 1202 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1204 1203 … … 1212 1211 { 1213 1212 /* Validate the cluster, checking for end of file. */ 1214 if ( idxCluster >= p Vol->cClusters1213 if ( idxCluster >= pFatCache->cClusters 1215 1214 || idxCluster < FAT_FIRST_DATA_CLUSTER) 1216 1215 { … … 1240 1239 * Worker for rtFsFatClusterMap_ReadClusterChain handling FAT16. 1241 1240 */ 1242 static int rtFsFatClusterMap_Fat16_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, uint32_t idxCluster, 1243 PRTFSFATCHAIN pChain) 1241 static int rtFsFatClusterMap_Fat16_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, PRTFSFATCHAIN pChain) 1244 1242 { 1245 1243 /* ASSUME that for FAT16 we cache the whole FAT in a single entry. That 1246 1244 way we don't need to deal with entries in different sectors and whatnot. */ 1247 1245 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1248 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1246 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1249 1247 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1250 1248 … … 1258 1256 { 1259 1257 /* Validate the cluster, checking for end of file. */ 1260 if ( idxCluster >= p Vol->cClusters1258 if ( idxCluster >= pFatCache->cClusters 1261 1259 || idxCluster < FAT_FIRST_DATA_CLUSTER) 1262 1260 { … … 1280 1278 * Worker for rtFsFatClusterMap_ReadClusterChain handling FAT32. 1281 1279 */ 1282 static int rtFsFatClusterMap_Fat32_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, uint32_t idxCluster, 1283 PRTFSFATCHAIN pChain) 1280 static int rtFsFatClusterMap_Fat32_ReadClusterChain(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, PRTFSFATCHAIN pChain) 1284 1281 { 1285 1282 /* Special case for empty files. */ … … 1291 1288 { 1292 1289 /* Validate the cluster, checking for end of file. */ 1293 if ( idxCluster >= p Vol->cClusters1290 if ( idxCluster >= pFatCache->cClusters 1294 1291 || idxCluster < FAT_FIRST_DATA_CLUSTER) 1295 1292 { … … 1306 1303 /* Get the next cluster. */ 1307 1304 uint8_t *pbEntry; 1308 rc = rtFsFatClusterMap_GetEntry(pFatCache, pVol,idxCluster * 4, &pbEntry);1305 rc = rtFsFatClusterMap_GetEntry(pFatCache, idxCluster * 4, &pbEntry); 1309 1306 if (RT_SUCCESS(rc)) 1310 1307 idxCluster = RT_MAKE_U32_FROM_U8(pbEntry[0], pbEntry[1], pbEntry[2], pbEntry[3]); … … 1333 1330 switch (pThis->enmFatType) 1334 1331 { 1335 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_Fat12_ReadClusterChain(pThis->pFatCache, pThis,idxFirstCluster, pChain);1336 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_Fat16_ReadClusterChain(pThis->pFatCache, pThis,idxFirstCluster, pChain);1337 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_Fat32_ReadClusterChain(pThis->pFatCache, pThis,idxFirstCluster, pChain);1332 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_Fat12_ReadClusterChain(pThis->pFatCache, idxFirstCluster, pChain); 1333 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_Fat16_ReadClusterChain(pThis->pFatCache, idxFirstCluster, pChain); 1334 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_Fat32_ReadClusterChain(pThis->pFatCache, idxFirstCluster, pChain); 1338 1335 default: 1339 1336 AssertFailedReturn(VERR_INTERNAL_ERROR_2); … … 1371 1368 1372 1369 /** Sets a FAT12 cluster value. */ 1373 static int rtFsFatClusterMap_SetCluster12(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1374 uint32_t idxCluster, uint32_t uValue) 1370 static int rtFsFatClusterMap_SetCluster12(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, uint32_t uValue) 1375 1371 { 1376 1372 /* ASSUME that for FAT12 we cache the whole FAT in a single entry. That 1377 1373 way we don't need to deal with entries in different sectors and whatnot. */ 1378 1374 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1379 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1375 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1380 1376 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1381 1377 AssertReturn(uValue < 0x1000, VERR_INTERNAL_ERROR_2); … … 1404 1400 1405 1401 /** Sets a FAT16 cluster value. */ 1406 static int rtFsFatClusterMap_SetCluster16(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1407 uint32_t idxCluster, uint32_t uValue) 1402 static int rtFsFatClusterMap_SetCluster16(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, uint32_t uValue) 1408 1403 { 1409 1404 /* ASSUME that for FAT16 we cache the whole FAT in a single entry. */ 1410 1405 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1411 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1406 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1412 1407 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1413 1408 AssertReturn(uValue < 0x10000, VERR_INTERNAL_ERROR_2); … … 1427 1422 1428 1423 /** Sets a FAT32 cluster value. */ 1429 static int rtFsFatClusterMap_SetCluster32(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1430 uint32_t idxCluster, uint32_t uValue) 1424 static int rtFsFatClusterMap_SetCluster32(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxCluster, uint32_t uValue) 1431 1425 { 1432 1426 AssertReturn(uValue < 0x10000000, VERR_INTERNAL_ERROR_2); … … 1435 1429 uint8_t *pbEntry; 1436 1430 uint32_t idxEntry; 1437 int rc = rtFsFatClusterMap_GetEntryEx(pFatCache, pVol,idxCluster * 4, &pbEntry, &idxEntry);1431 int rc = rtFsFatClusterMap_GetEntryEx(pFatCache, idxCluster * 4, &pbEntry, &idxEntry); 1438 1432 if (RT_SUCCESS(rc)) 1439 1433 { … … 1466 1460 switch (pThis->enmFatType) 1467 1461 { 1468 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_SetCluster12(pThis->pFatCache, pThis,idxCluster, FAT_FIRST_FAT12_EOC);1469 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_SetCluster16(pThis->pFatCache, pThis,idxCluster, FAT_FIRST_FAT16_EOC);1470 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_SetCluster32(pThis->pFatCache, pThis,idxCluster, FAT_FIRST_FAT32_EOC);1462 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_SetCluster12(pThis->pFatCache, idxCluster, FAT_FIRST_FAT12_EOC); 1463 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_SetCluster16(pThis->pFatCache, idxCluster, FAT_FIRST_FAT16_EOC); 1464 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_SetCluster32(pThis->pFatCache, idxCluster, FAT_FIRST_FAT32_EOC); 1471 1465 default: AssertFailedReturn(VERR_INTERNAL_ERROR_3); 1472 1466 } … … 1486 1480 switch (pThis->enmFatType) 1487 1481 { 1488 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_SetCluster12(pThis->pFatCache, pThis,idxCluster, 0);1489 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_SetCluster16(pThis->pFatCache, pThis,idxCluster, 0);1490 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_SetCluster32(pThis->pFatCache, pThis,idxCluster, 0);1482 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_SetCluster12(pThis->pFatCache, idxCluster, 0); 1483 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_SetCluster16(pThis->pFatCache, idxCluster, 0); 1484 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_SetCluster32(pThis->pFatCache, idxCluster, 0); 1491 1485 default: AssertFailedReturn(VERR_INTERNAL_ERROR_3); 1492 1486 } … … 1497 1491 * Worker for rtFsFatClusterMap_AllocateCluster that handles FAT12. 1498 1492 */ 1499 static int rtFsFatClusterMap_AllocateCluster12(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1500 uint32_t idxPrevCluster, uint32_t *pidxCluster) 1493 static int rtFsFatClusterMap_AllocateCluster12(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxPrevCluster, uint32_t *pidxCluster) 1501 1494 { 1502 1495 /* ASSUME that for FAT12 we cache the whole FAT in a single entry. That 1503 1496 way we don't need to deal with entries in different sectors and whatnot. */ 1504 1497 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1505 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1498 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1506 1499 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1507 1500 … … 1531 1524 uint32_t idxCluster = FAT_FIRST_DATA_CLUSTER; 1532 1525 uint32_t offFat = 3; 1533 while (idxCluster < p Vol->cClusters)1526 while (idxCluster < pFatCache->cClusters) 1534 1527 { 1535 1528 if (idxCluster & 1) … … 1594 1587 * Worker for rtFsFatClusterMap_AllocateCluster that handles FAT16. 1595 1588 */ 1596 static int rtFsFatClusterMap_AllocateCluster16(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1597 uint32_t idxPrevCluster, uint32_t *pidxCluster) 1589 static int rtFsFatClusterMap_AllocateCluster16(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxPrevCluster, uint32_t *pidxCluster) 1598 1590 { 1599 1591 /* ASSUME that for FAT16 we cache the whole FAT in a single entry. */ 1600 1592 AssertReturn(pFatCache->cEntries == 1, VERR_INTERNAL_ERROR_4); 1601 AssertReturn(pFatCache->cbEntry == p Vol->cbFat, VERR_INTERNAL_ERROR_4);1593 AssertReturn(pFatCache->cbEntry == pFatCache->cbFat, VERR_INTERNAL_ERROR_4); 1602 1594 AssertReturn(pFatCache->aEntries[0].offFat == 0, VERR_INTERNAL_ERROR_4); 1603 1595 … … 1623 1615 uint32_t idxCluster = RT_MIN(pFatCache->idxAllocHint, FAT_FIRST_DATA_CLUSTER); 1624 1616 uint32_t offFat = idxCluster * 2; 1625 uint32_t cClusters = p Vol->cClusters;1617 uint32_t cClusters = pFatCache->cClusters; 1626 1618 for (uint32_t i = 0; i < 2; i++) 1627 1619 { 1628 while (idxCluster < pVol->cClusters)1620 while (idxCluster < cClusters) 1629 1621 { 1630 1622 if ( pbFat[offFat + 0] != 0x00 … … 1663 1655 1664 1656 /* Wrap around to the start of the map. */ 1665 cClusters = RT_MIN(pFatCache->idxAllocHint, p Vol->cClusters);1657 cClusters = RT_MIN(pFatCache->idxAllocHint, pFatCache->cClusters); 1666 1658 idxCluster = FAT_FIRST_DATA_CLUSTER; 1667 1659 offFat = 4; … … 1675 1667 * Worker for rtFsFatClusterMap_AllocateCluster that handles FAT32. 1676 1668 */ 1677 static int rtFsFatClusterMap_AllocateCluster32(PRTFSFATCLUSTERMAPCACHE pFatCache, PRTFSFATVOL pVol, 1678 uint32_t idxPrevCluster, uint32_t *pidxCluster) 1669 static int rtFsFatClusterMap_AllocateCluster32(PRTFSFATCLUSTERMAPCACHE pFatCache, uint32_t idxPrevCluster, uint32_t *pidxCluster) 1679 1670 { 1680 1671 /* … … 1685 1676 if (idxPrevCluster != UINT32_MAX) 1686 1677 { 1687 rc = rtFsFatClusterMap_GetEntry(pFatCache, pVol,idxPrevCluster * 4, &pbEntry);1678 rc = rtFsFatClusterMap_GetEntry(pFatCache, idxPrevCluster * 4, &pbEntry); 1688 1679 if (RT_SUCCESS(rc)) 1689 1680 { … … 1701 1692 uint32_t idxCluster = RT_MIN(pFatCache->idxAllocHint, FAT_FIRST_DATA_CLUSTER); 1702 1693 uint32_t offFat = idxCluster * 4; 1703 uint32_t cClusters = p Vol->cClusters;1694 uint32_t cClusters = pFatCache->cClusters; 1704 1695 for (uint32_t i = 0; i < 2; i++) 1705 1696 { 1706 while (idxCluster < pVol->cClusters)1697 while (idxCluster < cClusters) 1707 1698 { 1708 1699 /* Note! This could be done in cache entry chunks. */ 1709 1700 uint32_t idxEntry; 1710 rc = rtFsFatClusterMap_GetEntryEx(pFatCache, pVol,offFat, &pbEntry, &idxEntry);1701 rc = rtFsFatClusterMap_GetEntryEx(pFatCache, offFat, &pbEntry, &idxEntry); 1711 1702 if (RT_SUCCESS(rc)) 1712 1703 { … … 1735 1726 if (idxPrevCluster != UINT32_MAX) 1736 1727 { 1737 rc = rtFsFatClusterMap_GetEntryEx(pFatCache, pVol,idxPrevCluster * 4, &pbEntry, &idxEntry);1728 rc = rtFsFatClusterMap_GetEntryEx(pFatCache, idxPrevCluster * 4, &pbEntry, &idxEntry); 1738 1729 if (RT_SUCCESS(rc)) 1739 1730 { … … 1747 1738 { 1748 1739 /* Try free the cluster. */ 1749 int rc2 = rtFsFatClusterMap_GetEntryEx(pFatCache, pVol,offFat, &pbEntry, &idxEntry);1740 int rc2 = rtFsFatClusterMap_GetEntryEx(pFatCache, offFat, &pbEntry, &idxEntry); 1750 1741 if (RT_SUCCESS(rc2)) 1751 1742 { … … 1771 1762 1772 1763 /* Wrap around to the start of the map. */ 1773 cClusters = RT_MIN(pFatCache->idxAllocHint, p Vol->cClusters);1764 cClusters = RT_MIN(pFatCache->idxAllocHint, pFatCache->cClusters); 1774 1765 idxCluster = FAT_FIRST_DATA_CLUSTER; 1775 1766 offFat = 4; … … 1796 1787 switch (pThis->enmFatType) 1797 1788 { 1798 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_AllocateCluster12(pThis->pFatCache, pThis,idxPrevCluster, pidxCluster);1799 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_AllocateCluster16(pThis->pFatCache, pThis,idxPrevCluster, pidxCluster);1800 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_AllocateCluster32(pThis->pFatCache, pThis,idxPrevCluster, pidxCluster);1789 case RTFSFATTYPE_FAT12: return rtFsFatClusterMap_AllocateCluster12(pThis->pFatCache, idxPrevCluster, pidxCluster); 1790 case RTFSFATTYPE_FAT16: return rtFsFatClusterMap_AllocateCluster16(pThis->pFatCache, idxPrevCluster, pidxCluster); 1791 case RTFSFATTYPE_FAT32: return rtFsFatClusterMap_AllocateCluster32(pThis->pFatCache, idxPrevCluster, pidxCluster); 1801 1792 default: AssertFailedReturn(VERR_INTERNAL_ERROR_3); 1802 1793 }
Note:
See TracChangeset
for help on using the changeset viewer.