42 if (iAtt&KEntryAttModified) |
52 if (iAtt&KEntryAttModified) |
43 TRAP_IGNORE(FlushAllL()); |
53 TRAP_IGNORE(FlushAllL()); |
44 } |
54 } |
45 |
55 |
46 delete[] iSeekIndex; |
56 delete[] iSeekIndex; |
47 } |
57 } |
48 |
58 |
49 |
59 |
50 void CFatFileCB::CreateSeekIndex() |
60 void CFatFileCB::CreateSeekIndex() |
51 // |
61 // |
52 // Create a seek index |
62 // Create a seek index |
53 // |
63 // |
54 { |
64 { |
55 |
65 |
56 iSeekIndex = new TUint32[KSeekIndexSize]; |
66 iSeekIndex = new TUint32[KSeekIndexSize]; |
57 if (iSeekIndex == NULL) |
67 if (iSeekIndex == NULL) |
58 return; |
68 return; |
59 |
69 |
60 Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize); |
70 Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize); |
61 |
71 |
62 iSeekIndexSize=CalcSeekIndexSize(Size()); |
72 iSeekIndexSize=CalcSeekIndexSize(Size()); |
63 } |
73 } |
64 |
74 |
65 TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset) |
75 TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset) |
66 // |
76 // |
67 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster |
77 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster |
68 // Return aNewRelCluster-aCurrentPos.iCluster |
78 // Return aNewRelCluster-aCurrentPos.iCluster |
69 // |
79 // |
70 { |
80 { |
71 TInt clusterOffset=aClusterOffset; |
81 TInt clusterOffset=aClusterOffset; |
72 TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1; |
82 TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1; |
73 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
83 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
74 |
84 |
75 while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0) |
85 while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0) |
76 { |
86 { |
77 seekPos--; |
87 seekPos--; |
78 clusterOffset--; |
88 clusterOffset--; |
79 } |
89 } |
80 if (clusterOffset==0) // Counted back to the current cluster |
90 if (clusterOffset==0) // Counted back to the current cluster |
81 return(aClusterOffset); |
91 return(aClusterOffset); |
82 if (seekPos<0) |
92 if (seekPos<0) |
83 { |
93 { |
84 iCurrentPos.iCluster=iStartCluster; |
94 iCurrentPos.iCluster=iStartCluster; |
85 return(aNewRelCluster); |
95 return(aNewRelCluster); |
86 } |
96 } |
87 |
97 |
88 iCurrentPos.iCluster=iSeekIndex[seekPos]; |
98 iCurrentPos.iCluster=iSeekIndex[seekPos]; |
89 return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize)); |
99 return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize)); |
90 } |
100 } |
91 |
101 |
92 void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster) |
102 void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster) |
93 // |
103 // |
94 // Sets a value in the seekindex |
104 // Sets a value in the seekindex |
95 // |
105 // |
96 { |
106 { |
97 |
107 |
98 TInt seekPos=(aRelCluster>>iSeekIndexSize)-1; |
108 TInt seekPos=(aRelCluster>>iSeekIndexSize)-1; |
99 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
109 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
100 __ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2)); |
110 __ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2)); |
101 iSeekIndex[seekPos] = aStoredCluster; |
111 iSeekIndex[seekPos] = aStoredCluster; |
102 } |
112 } |
103 |
113 |
104 TBool CFatFileCB::IsSeekBackwards(TUint aPos) |
114 TBool CFatFileCB::IsSeekBackwards(TUint aPos) |
105 // |
115 // |
106 // Return true if aPos<currentPos |
116 // Return true if aPos<currentPos |
107 // |
117 // |
108 { |
118 { |
109 |
119 |
110 TUint cluster=iCurrentPos.iCluster<<ClusterSizeLog2(); |
120 TUint cluster=iCurrentPos.iCluster<<ClusterSizeLog2(); |
111 TInt offset=ClusterRelativePos(iCurrentPos.iPos); |
121 TInt offset=ClusterRelativePos(iCurrentPos.iPos); |
112 TUint currentPos=cluster+offset; |
122 TUint currentPos=cluster+offset; |
113 return(aPos<currentPos); |
123 return(aPos<currentPos); |
114 } |
124 } |
115 |
125 |
116 void CFatFileCB::CheckPosL(TUint aPos) |
126 void CFatFileCB::CheckPosL(TUint aPos) |
117 // |
127 // |
118 // Check that the file is positioned correctly. |
128 // Check that the file is positioned correctly. |
119 // If aPos<currentPos attempt to guess the new position. |
129 // If aPos<currentPos attempt to guess the new position. |
120 // |
130 // |
121 { |
131 { |
122 __PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos); |
132 __PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos); |
123 if (aPos==iCurrentPos.iPos) |
133 if (aPos==iCurrentPos.iPos) |
124 return; |
134 return; |
125 __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd)); |
135 __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd)); |
126 |
136 |
127 if (iFileSizeModified && IsSeekBackwards(aPos)) |
137 if (iFileSizeModified && IsSeekBackwards(aPos)) |
128 FlushDataL(); |
138 FlushDataL(); |
129 |
139 |
130 TUint newRelCluster=aPos>>ClusterSizeLog2(); |
140 TUint newRelCluster=aPos>>ClusterSizeLog2(); |
131 if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) ) |
141 if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) ) |
132 newRelCluster--; |
142 newRelCluster--; |
133 TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2(); |
143 TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2(); |
134 if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) ) |
144 if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) ) |
135 oldRelCluster--; |
145 oldRelCluster--; |
136 TInt clusterOffset=newRelCluster-oldRelCluster; |
146 TInt clusterOffset=newRelCluster-oldRelCluster; |
137 TInt oldCluster=iCurrentPos.iCluster; |
147 TInt oldCluster=iCurrentPos.iCluster; |
138 iCurrentPos.iPos=aPos; |
148 iCurrentPos.iPos=aPos; |
139 if (clusterOffset==0) |
149 if (clusterOffset==0) |
140 return; |
150 return; |
141 TInt seekOffset=clusterOffset; |
151 TInt seekOffset=clusterOffset; |
142 if (iSeekIndex!=NULL) |
152 if (iSeekIndex!=NULL) |
143 { // Can alter iCurrentPos.iCluster |
153 { // Can alter iCurrentPos.iCluster |
144 seekOffset=SeekToPosition(newRelCluster,seekOffset); |
154 seekOffset=SeekToPosition(newRelCluster,seekOffset); |
145 if (seekOffset==0) |
155 if (seekOffset==0) |
146 return; |
156 return; |
147 } |
157 } |
148 if (clusterOffset==-1 && seekOffset!=1) |
158 if (clusterOffset==-1 && seekOffset!=1) |
149 { // Check previous cluster |
159 { // Check previous cluster |
150 TInt cluster=oldCluster-1; |
160 TInt cluster=oldCluster-1; |
151 if (FAT().GetNextClusterL(cluster) && cluster==oldCluster) |
161 if (FAT().GetNextClusterL(cluster) && cluster==oldCluster) |
152 { |
162 { |
153 iCurrentPos.iCluster=oldCluster-1; |
163 iCurrentPos.iCluster=oldCluster-1; |
154 return; |
164 return; |
155 } |
165 } |
156 } |
166 } |
157 if (seekOffset<0) |
167 if (seekOffset<0) |
158 { |
168 { |
159 seekOffset=newRelCluster; |
169 seekOffset=newRelCluster; |
160 iCurrentPos.iCluster=iStartCluster; |
170 iCurrentPos.iCluster=iStartCluster; |
161 } |
171 } |
162 while (seekOffset--) |
172 while (seekOffset--) |
163 { |
173 { |
164 if (!FAT().GetNextClusterL(iCurrentPos.iCluster)) |
174 if (!FAT().GetNextClusterL(iCurrentPos.iCluster)) |
165 { |
175 { |
166 __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1")); |
176 __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1")); |
167 User::Leave(KErrCorrupt); |
177 User::Leave(KErrCorrupt); |
168 } |
178 } |
169 TInt cluster=newRelCluster-seekOffset; |
179 TInt cluster=newRelCluster-seekOffset; |
170 if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster) |
180 if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster) |
171 SetSeekIndexValueL(cluster,iCurrentPos.iCluster); |
181 SetSeekIndexValueL(cluster,iCurrentPos.iCluster); |
172 } |
182 } |
173 } |
183 } |
174 |
184 |
175 void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos) |
185 void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos) |
176 // |
186 // |
177 // Initialize FileCB from entry data |
187 // Initialize FileCB from entry data |
178 // |
188 // |
179 { |
189 { |
180 |
190 |
181 __PRINT(_L("CFatFileCB::SetL")); |
191 __PRINT(_L("CFatFileCB::SetL")); |
182 SetSize(aFatDirEntry.Size()); |
192 SetSize(aFatDirEntry.Size()); |
183 iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry); |
193 iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry); |
184 iStartCluster=iCurrentPos.iCluster; |
194 iStartCluster=iCurrentPos.iCluster; |
185 iCurrentPos.iPos=0; |
195 iCurrentPos.iPos=0; |
186 iAtt=aFatDirEntry.Attributes(); |
196 iAtt=aFatDirEntry.Attributes(); |
187 iModified= aFatDirEntry.Time(FatMount().TimeOffset()); |
197 iModified= aFatDirEntry.Time(FatMount().TimeOffset()); |
188 iShare=aShare; |
198 iShare=aShare; |
189 iFileDirPos=aPos; |
199 iFileDirPos=aPos; |
190 |
200 |
191 SetMaxSupportedSize(KMaxSupportedFatFileSize); |
201 SetMaxSupportedSize(KMaxSupportedFatFileSize); |
192 } |
202 } |
193 |
203 |
194 //----------------------------------------------------------------------------- |
204 //----------------------------------------------------------------------------- |
195 // from CFileCB::MExtendedFileInterface |
205 // from CFileCB::MExtendedFileInterface |
196 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset) |
206 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset) |
197 { |
207 { |
198 __PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength); |
208 __PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength); |
199 |
209 |
200 if((TUint64)aPos > KMaxSupportedFatFileSize-1) |
210 if((TUint64)aPos > KMaxSupportedFatFileSize-1) |
201 User::Leave(KErrNotSupported); //-- max. position in the file is 0xFFFFFFFE |
211 User::Leave(KErrNotSupported); //-- max. position in the file is 0xFFFFFFFE |
202 |
212 |
203 FatMount().CheckStateConsistentL(); |
213 FatMount().CheckStateConsistentL(); |
204 |
214 |
205 CheckPosL(I64LOW(aPos)); |
215 CheckPosL(I64LOW(aPos)); |
206 |
216 |
207 const TUint startPos = iCurrentPos.iPos; |
217 const TUint startPos = iCurrentPos.iPos; |
208 const TUint curSize = (TUint)Size(); |
218 const TUint curSize = (TUint)Size(); |
209 const TUint length = (TUint)aLength; |
219 const TUint length = (TUint)aLength; |
210 |
220 |
211 if((startPos + length > curSize) || (startPos > startPos + length) ) |
221 if((startPos + length > curSize) || (startPos > startPos + length) ) |
212 aLength=curSize-startPos; |
222 aLength=curSize-startPos; |
213 |
223 |
214 FatMount().ReadFromClusterListL(iCurrentPos,aLength,aDes,aMessage,aOffset); |
224 FatMount().ReadFromClusterListL(iCurrentPos,aLength,aDes,aMessage,aOffset); |
215 aLength=iCurrentPos.iPos-startPos; |
225 aLength=iCurrentPos.iPos-startPos; |
216 } |
226 } |
217 |
227 |
218 |
228 |
219 void CFatFileCB::ReadL(TInt aFilePos,TInt& aLength,const TAny* aTrg,const RMessagePtr2& aMessage) |
229 void CFatFileCB::ReadL(TInt aFilePos,TInt& aLength,const TAny* aTrg,const RMessagePtr2& aMessage) |
220 { |
230 { |
221 ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0); |
231 ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0); |
222 } |
232 } |
223 |
233 |
224 //----------------------------------------------------------------------------- |
234 //----------------------------------------------------------------------------- |
225 // from CFileCB::MExtendedFileInterface |
235 // from CFileCB::MExtendedFileInterface |
226 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset) |
236 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset) |
227 { |
237 { |
228 __PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength); |
238 __PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength); |
229 // FAT supports 32 bits only for file size |
239 // FAT supports 32 bits only for file size |
230 TUint64 endPos = aPos + aLength; |
240 TUint64 endPos = aPos + aLength; |
231 if(endPos > KMaxSupportedFatFileSize) |
241 if(endPos > KMaxSupportedFatFileSize) |
232 User::Leave(KErrNotSupported); |
242 User::Leave(KErrNotSupported); |
233 |
243 |
234 FatMount().CheckStateConsistentL(); |
244 FatMount().CheckStateConsistentL(); |
235 FatMount().CheckWritableL(); |
245 FatMount().CheckWritableL(); |
236 const TUint pos = I64LOW(aPos); |
246 const TUint pos = I64LOW(aPos); |
237 CheckPosL(pos); |
247 CheckPosL(pos); |
238 |
248 |
239 const TUint startCluster = (TUint)iStartCluster; |
249 const TUint startCluster = (TUint)iStartCluster; |
240 const TUint length = (TUint)aLength; |
250 const TUint length = (TUint)aLength; |
241 |
251 |
242 endPos = iCurrentPos.iPos + length; |
252 endPos = iCurrentPos.iPos + length; |
243 if ((endPos > (TUint)Size()) || |
253 if ((endPos > (TUint)Size()) || |
244 (iCurrentPos.iPos > endPos) ) // Overflow condition |
254 (iCurrentPos.iPos > endPos) ) // Overflow condition |
245 DoSetSizeL(iCurrentPos.iPos+length,EFalse); |
255 DoSetSizeL(iCurrentPos.iPos+length,EFalse); |
246 |
256 |
247 TUint startPos=iCurrentPos.iPos; |
257 TUint startPos=iCurrentPos.iPos; |
248 TInt badcluster=0; |
258 TInt badcluster=0; |
249 TInt goodcluster=0; |
259 TInt goodcluster=0; |
250 |
260 |
251 TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster)); |
261 TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster)); |
252 |
262 |
253 if (ret == KErrCorrupt || ret == KErrDied) |
263 if (ret == KErrCorrupt || ret == KErrDied) |
254 { |
264 { |
255 if(startCluster == 0) |
265 if(startCluster == 0) |
256 { //Empty File, revert all the clusters allocated. |
266 { //Empty File, revert all the clusters allocated. |
257 TInt cluster = iStartCluster; |
267 TInt cluster = iStartCluster; |
258 iStartCluster = 0; |
268 iStartCluster = 0; |
259 SetSize(0); |
269 SetSize(0); |
260 FlushAllL(); |
270 FlushAllL(); |
261 |
271 |
262 iCurrentPos.iCluster = 0; |
272 iCurrentPos.iCluster = 0; |
263 iCurrentPos.iPos = 0; |
273 iCurrentPos.iPos = 0; |
264 |
274 |
265 FAT().FreeClusterListL(cluster); |
275 FAT().FreeClusterListL(cluster); |
266 FAT().FlushL(); |
276 FAT().FlushL(); |
267 } |
277 } |
268 else |
278 else |
269 { //Calculate the clusters required based on file size, revert extra clusters if allocated. |
279 { //Calculate the clusters required based on file size, revert extra clusters if allocated. |
270 const TUint curSize = (TUint)Size(); |
280 const TUint curSize = (TUint)Size(); |
271 TUint ClustersNeeded = curSize >> ClusterSizeLog2(); |
281 TUint ClustersNeeded = curSize >> ClusterSizeLog2(); |
272 if(curSize > (ClustersNeeded << ClusterSizeLog2())) |
282 if(curSize > (ClustersNeeded << ClusterSizeLog2())) |
273 { |
283 { |
274 ClustersNeeded++; |
284 ClustersNeeded++; |
275 } |
285 } |
276 |
286 |
277 TInt cluster = iStartCluster; |
287 TInt cluster = iStartCluster; |
278 while(--ClustersNeeded) |
288 while(--ClustersNeeded) |
279 { |
289 { |
280 FAT().GetNextClusterL(cluster); |
290 FAT().GetNextClusterL(cluster); |
281 } |
291 } |
282 |
292 |
283 iCurrentPos.iCluster = cluster; |
293 iCurrentPos.iCluster = cluster; |
284 |
294 |
285 if (FAT().GetNextClusterL(cluster)) |
295 if (FAT().GetNextClusterL(cluster)) |
286 { |
296 { |
287 FAT().FreeClusterListL(cluster); |
297 FAT().FreeClusterListL(cluster); |
288 } |
298 } |
289 |
299 |
290 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
300 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
291 FAT().FlushL(); |
301 FAT().FlushL(); |
292 } |
302 } |
293 } |
303 } |
294 |
304 |
295 User::LeaveIfError(ret); |
305 User::LeaveIfError(ret); |
296 |
306 |
297 if(badcluster != 0) |
307 if(badcluster != 0) |
298 { |
308 { |
299 if(iStartCluster == badcluster) |
309 if(iStartCluster == badcluster) |
300 { |
310 { |
301 iStartCluster = goodcluster; |
311 iStartCluster = goodcluster; |
302 FlushStartClusterL(); |
312 FlushStartClusterL(); |
303 } |
313 } |
304 else |
314 else |
305 { |
315 { |
306 TInt aCluster = iStartCluster; |
316 TInt aCluster = iStartCluster; |
307 do |
317 do |
308 { |
318 { |
309 if((TUint)badcluster == FAT().ReadL(aCluster)) |
319 if((TUint)badcluster == FAT().ReadL(aCluster)) |
310 { |
320 { |
311 FAT().WriteL(aCluster, goodcluster); |
321 FAT().WriteL(aCluster, goodcluster); |
312 FAT().FlushL(); |
322 FAT().FlushL(); |
313 break; |
323 break; |
314 } |
324 } |
315 } |
325 } |
316 while(FAT().GetNextClusterL(aCluster)); |
326 while(FAT().GetNextClusterL(aCluster)); |
317 } |
327 } |
318 } |
328 } |
319 aLength=iCurrentPos.iPos-startPos; |
329 aLength=iCurrentPos.iPos-startPos; |
320 |
330 |
321 if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size()) |
331 if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size()) |
322 { |
332 { |
323 WriteFileSizeL(pos+aLength); |
333 WriteFileSizeL(pos+aLength); |
324 } |
334 } |
325 |
335 |
326 } |
336 } |
327 |
337 |
328 |
338 |
329 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage) |
339 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage) |
330 { |
340 { |
331 WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0); |
341 WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0); |
332 } |
342 } |
333 |
343 |
334 |
344 |
335 |
345 |
336 //----------------------------------------------------------------------------- |
346 //----------------------------------------------------------------------------- |
337 |
347 |
338 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize) |
348 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize) |
339 // |
349 // |
340 // Resize the seek index to accomodate a larger or smaller filesize |
350 // Resize the seek index to accomodate a larger or smaller filesize |
341 // Assumes KSeekIndexSize is a power of 2. |
351 // Assumes KSeekIndexSize is a power of 2. |
342 // |
352 // |
343 { |
353 { |
344 |
354 |
345 TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult); |
355 TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult); |
346 |
356 |
347 |
357 |
348 TInt index=0; |
358 TInt index=0; |
349 TInt indexEnd=KSeekIndexSize; |
359 TInt indexEnd=KSeekIndexSize; |
350 TInt newValEnd=maxNewIndex; |
360 TInt newValEnd=maxNewIndex; |
351 |
361 |
352 if (iSeekIndexSize<aNewMult) |
362 if (iSeekIndexSize<aNewMult) |
353 { |
363 { |
354 TInt newVal=index; |
364 TInt newVal=index; |
355 TInt step=1<<(aNewMult-iSeekIndexSize); |
365 TInt step=1<<(aNewMult-iSeekIndexSize); |
356 index+=step-1; |
366 index+=step-1; |
357 while(index<indexEnd && newVal<newValEnd) |
367 while(index<indexEnd && newVal<newValEnd) |
358 { |
368 { |
359 iSeekIndex[newVal] = iSeekIndex[index]; |
369 iSeekIndex[newVal] = iSeekIndex[index]; |
360 newVal++; |
370 newVal++; |
361 index+=step; |
371 index+=step; |
362 } |
372 } |
363 while(newVal<indexEnd) |
373 while(newVal<indexEnd) |
364 iSeekIndex[newVal++] = 0; |
374 iSeekIndex[newVal++] = 0; |
365 } |
375 } |
366 else |
376 else |
367 { |
377 { |
368 TInt diffSize = iSeekIndexSize-aNewMult; |
378 TInt diffSize = iSeekIndexSize-aNewMult; |
369 TInt oldVal=(KSeekIndexSize>>diffSize) - 1; |
379 TInt oldVal=(KSeekIndexSize>>diffSize) - 1; |
370 TInt newVal=indexEnd-1; |
380 TInt newVal=indexEnd-1; |
371 TInt skip=(1<<diffSize)-1; |
381 TInt skip=(1<<diffSize)-1; |
372 |
382 |
373 if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2) |
383 if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2) |
374 { |
384 { |
375 ClearIndex(0); //-- Invalidate every entry. |
385 ClearIndex(0); //-- Invalidate every entry. |
376 } |
386 } |
377 else |
387 else |
378 { |
388 { |
379 while(newVal>=index) |
389 while(newVal>=index) |
380 { |
390 { |
381 |
391 |
382 iSeekIndex[newVal--] = iSeekIndex[oldVal--]; |
392 iSeekIndex[newVal--] = iSeekIndex[oldVal--]; |
383 |
393 |
384 |
394 |
385 for(TInt i=skip;i>0;i--) |
395 for(TInt i=skip;i>0;i--) |
386 { |
396 { |
387 iSeekIndex[newVal--] = 0; |
397 iSeekIndex[newVal--] = 0; |
388 |
398 |
389 } |
399 } |
390 } |
400 } |
391 } |
401 } |
392 } |
402 } |
393 iSeekIndexSize=aNewMult; |
403 iSeekIndexSize=aNewMult; |
394 } |
404 } |
395 |
405 |
396 |
406 |
397 /** |
407 /** |
398 Zero freed clusters in the index |
408 Zero freed clusters in the index |
399 |
409 |
400 @param aNewSize new size of the file that the index corresponds to. |
410 @param aNewSize new size of the file that the index corresponds to. |
401 if = 0 all existing index will be zero filled |
411 if = 0 all existing index will be zero filled |
402 */ |
412 */ |
403 void CFatFileCB::ClearIndex(TUint aNewSize) |
413 void CFatFileCB::ClearIndex(TUint aNewSize) |
404 { |
414 { |
405 |
415 |
406 if (!iSeekIndex) |
416 if (!iSeekIndex) |
407 return; |
417 return; |
408 |
418 |
409 if(aNewSize==0) |
419 if(aNewSize==0) |
410 { |
420 { |
411 //-- zero fill all the array |
421 //-- zero fill all the array |
412 Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32)); |
422 Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32)); |
413 return; |
423 return; |
414 } |
424 } |
415 |
425 |
416 // Files that fill up a cluster exactly do not have a trailing empty |
426 // Files that fill up a cluster exactly do not have a trailing empty |
417 // cluster. So the entry for that position must also be invalidated |
427 // cluster. So the entry for that position must also be invalidated |
418 aNewSize--; |
428 aNewSize--; |
419 TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2()); |
429 TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2()); |
420 |
430 |
421 TInt indexLen=KSeekIndexSize-firstInvalidIndex; |
431 TInt indexLen=KSeekIndexSize-firstInvalidIndex; |
422 |
432 |
423 Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32)); |
433 Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32)); |
424 } |
434 } |
425 |
435 |
426 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize) |
436 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize) |
427 // |
437 // |
428 // Find the nearest power of 2 > aSize |
438 // Find the nearest power of 2 > aSize |
429 // |
439 // |
430 { |
440 { |
431 TInt count = 0; |
441 TInt count = 0; |
432 const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128 |
442 const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128 |
433 if (aSize<=indexSize) |
443 if (aSize<=indexSize) |
434 return(count); |
444 return(count); |
435 |
445 |
436 while((aSize>>=1)>0) |
446 while((aSize>>=1)>0) |
437 { |
447 { |
438 count++; |
448 count++; |
439 } |
449 } |
440 return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1); |
450 return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1); |
441 } |
451 } |
442 |
452 |
443 //----------------------------------------------------------------------------- |
453 //----------------------------------------------------------------------------- |
444 |
454 |
445 void CFatFileCB::SetSizeL(TInt64 aSize) |
455 void CFatFileCB::SetSizeL(TInt64 aSize) |
446 { |
456 { |
447 __PRINT(_L("CFatFileCB::SetSizeL")); |
457 __PRINT(_L("CFatFileCB::SetSizeL")); |
448 |
458 |
449 // FAT supports 32 bits only for file size |
459 // FAT supports 32 bits only for file size |
450 if (I64HIGH(aSize)) |
460 if (I64HIGH(aSize)) |
451 User::Leave(KErrNotSupported); |
461 User::Leave(KErrNotSupported); |
452 |
462 |
453 if(FatMount().IsRuggedFSys()) |
463 if(FatMount().IsRuggedFSys()) |
454 DoSetSizeL(I64LOW(aSize),ETrue); |
464 DoSetSizeL(I64LOW(aSize),ETrue); |
455 else |
465 else |
456 DoSetSizeL(I64LOW(aSize),EFalse); |
466 DoSetSizeL(I64LOW(aSize),EFalse); |
457 } |
467 } |
458 |
468 |
459 |
469 |
460 void CFatFileCB::SetSizeL(TInt aSize) |
470 void CFatFileCB::SetSizeL(TInt aSize) |
461 // |
471 // |
462 // Envelope function around DoSetSizeL to enable aSize to |
472 // Envelope function around DoSetSizeL to enable aSize to |
463 // be written to disk for rugged fat file system |
473 // be written to disk for rugged fat file system |
464 // |
474 // |
465 { |
475 { |
466 SetSizeL(TInt64(aSize)); |
476 SetSizeL(TInt64(aSize)); |
467 } |
477 } |
468 |
478 |
469 void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite) |
479 void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite) |
470 // |
480 // |
471 // Extend or truncate the file. |
481 // Extend or truncate the file. |
472 // Expects the modified attribute and iSize are set afterwards. |
482 // Expects the modified attribute and iSize are set afterwards. |
473 // Does not alter iCurrentPos, the current file position. |
483 // Does not alter iCurrentPos, the current file position. |
474 // Writes size of file to disk if aIsSizeWrite set |
484 // Writes size of file to disk if aIsSizeWrite set |
475 // |
485 // |
476 { |
486 { |
477 __PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite); |
487 __PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite); |
478 |
488 |
479 FatMount().CheckStateConsistentL(); |
489 FatMount().CheckStateConsistentL(); |
480 FatMount().CheckWritableL(); |
490 FatMount().CheckWritableL(); |
481 |
491 |
482 |
492 |
483 // Can not change the file size if it is clamped |
493 // Can not change the file size if it is clamped |
484 if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0) |
494 if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0) |
485 User::Leave(KErrInUse); |
495 User::Leave(KErrInUse); |
486 |
496 |
487 iFileSizeModified=ETrue; |
497 iFileSizeModified=ETrue; |
488 |
498 |
489 TInt newIndexMult=CalcSeekIndexSize(aSize); |
499 TInt newIndexMult=CalcSeekIndexSize(aSize); |
490 if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize) |
500 if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize) |
491 ResizeIndex(newIndexMult,aSize); |
501 ResizeIndex(newIndexMult,aSize); |
492 if (aSize == 0) |
502 if (aSize == 0) |
493 { |
503 { |
494 if (Size() != 0) |
504 if (Size() != 0) |
495 { |
505 { |
496 ClearIndex(0); //-- clear seek index array |
506 ClearIndex(0); //-- clear seek index array |
497 TInt cluster=iStartCluster; |
507 TInt cluster=iStartCluster; |
498 iStartCluster = 0; |
508 iStartCluster = 0; |
499 SetSize(0); |
509 SetSize(0); |
500 FlushAllL(); |
510 FlushAllL(); |
501 CheckPosL(0); |
511 CheckPosL(0); |
502 FAT().FreeClusterListL(cluster); |
512 FAT().FreeClusterListL(cluster); |
503 FAT().FlushL(); |
513 FAT().FlushL(); |
504 } |
514 } |
505 return; |
515 return; |
506 } |
516 } |
507 if (aSize<(TUint)Size()) |
517 if (aSize<(TUint)Size()) |
508 { |
518 { |
509 if(aIsSizeWrite) // write file size if decreasing |
519 if(aIsSizeWrite) // write file size if decreasing |
510 WriteFileSizeL(aSize); |
520 WriteFileSizeL(aSize); |
511 CheckPosL(aSize); |
521 CheckPosL(aSize); |
512 TInt cluster=iCurrentPos.iCluster; |
522 TInt cluster=iCurrentPos.iCluster; |
513 if (FAT().GetNextClusterL(cluster)) |
523 if (FAT().GetNextClusterL(cluster)) |
514 { |
524 { |
515 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
525 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
516 FAT().FreeClusterListL(cluster); |
526 FAT().FreeClusterListL(cluster); |
517 } |
527 } |
518 ClearIndex(aSize); |
528 ClearIndex(aSize); |
519 FAT().FlushL(); |
529 FAT().FlushL(); |
520 return; |
530 return; |
521 } |
531 } |
522 |
532 |
523 TUint newSize=aSize>>ClusterSizeLog2(); // Number of clusters we now need |
533 TUint newSize=aSize>>ClusterSizeLog2(); // Number of clusters we now need |
524 if (aSize > (newSize<<ClusterSizeLog2())) |
534 if (aSize > (newSize<<ClusterSizeLog2())) |
525 newSize++; // File size is not an exact multiple of cluster size |
535 newSize++; // File size is not an exact multiple of cluster size |
526 // Increment the number of clusters required to accomodate tail |
536 // Increment the number of clusters required to accomodate tail |
527 |
537 |
528 if (iStartCluster==0) |
538 if (iStartCluster==0) |
529 { |
539 { |
530 //-- FAT().FreeClusterHint() will give us a hint of the last free cluster |
540 //-- FAT().FreeClusterHint() will give us a hint of the last free cluster |
531 ClearIndex(0); //-- clear seek index array |
541 ClearIndex(0); //-- clear seek index array |
532 TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint()); |
542 TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint()); |
533 FAT().FlushL(); |
543 FAT().FlushL(); |
534 iCurrentPos.iCluster=tempStartCluster; |
544 iCurrentPos.iCluster=tempStartCluster; |
535 iStartCluster=tempStartCluster; |
545 iStartCluster=tempStartCluster; |
536 SetSize(aSize); |
546 SetSize(aSize); |
537 FlushAllL(); |
547 FlushAllL(); |
538 } |
548 } |
539 else |
549 else |
540 { |
550 { |
541 const TUint curSize = (TUint)Size(); |
551 const TUint curSize = (TUint)Size(); |
542 TUint oldSize=curSize>>ClusterSizeLog2(); // Number of clusters we had previously |
552 TUint oldSize=curSize>>ClusterSizeLog2(); // Number of clusters we had previously |
543 if (curSize>(oldSize<<ClusterSizeLog2())) |
553 if (curSize>(oldSize<<ClusterSizeLog2())) |
544 oldSize++; |
554 oldSize++; |
545 |
555 |
546 TInt newClusters=newSize-oldSize; // Number of clusters we need to prepare |
556 TInt newClusters=newSize-oldSize; // Number of clusters we need to prepare |
547 if (newClusters) |
557 if (newClusters) |
548 { |
558 { |
549 TEntryPos currentPos=iCurrentPos; |
559 TEntryPos currentPos=iCurrentPos; |
550 CheckPosL(Size()); |
560 CheckPosL(Size()); |
551 FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster); |
561 FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster); |
552 iCurrentPos=currentPos; |
562 iCurrentPos=currentPos; |
553 } |
563 } |
554 FAT().FlushL(); |
564 FAT().FlushL(); |
555 if(aIsSizeWrite) // write file size if increasing |
565 if(aIsSizeWrite) // write file size if increasing |
556 WriteFileSizeL(aSize); |
566 WriteFileSizeL(aSize); |
557 } |
567 } |
558 } |
568 } |
559 |
569 |
560 //----------------------------------------------------------------------------- |
570 //----------------------------------------------------------------------------- |
561 /** |
571 /** |
562 Set the entry's attributes and modified time. |
572 Set the entry's attributes and modified time. |
563 */ |
573 */ |
564 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask) |
574 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask) |
565 { |
575 { |
566 __PRINT(_L("CFatFileCB::SetEntryL")); |
576 __PRINT(_L("CFatFileCB::SetEntryL")); |
567 |
577 |
568 FatMount().CheckStateConsistentL(); |
578 FatMount().CheckStateConsistentL(); |
569 FatMount().CheckWritableL(); |
579 FatMount().CheckWritableL(); |
570 |
580 |
571 TUint setAttMask=aSetAttMask&KEntryAttMaskSupported; |
581 TUint setAttMask=aSetAttMask&KEntryAttMaskSupported; |
572 if (setAttMask|aClearAttMask) |
582 if (setAttMask|aClearAttMask) |
573 { |
583 { |
574 iAtt|=setAttMask; |
584 iAtt|=setAttMask; |
575 iAtt&=(~aClearAttMask); |
585 iAtt&=(~aClearAttMask); |
576 } |
586 } |
577 if (aSetAttMask&KEntryAttModified) |
587 if (aSetAttMask&KEntryAttModified) |
578 iModified=aTime; |
588 iModified=aTime; |
579 iAtt|=KEntryAttModified; |
589 iAtt|=KEntryAttModified; |
580 } |
590 } |
581 |
591 |
582 /** |
592 /** |
583 This is a RuggedFAT - specific method. Writes file size to the corresponding field of this |
593 This is a RuggedFAT - specific method. Writes file size to the corresponding field of this |
584 file direcrory entry. |
594 file direcrory entry. |
585 */ |
595 */ |
586 void CFatFileCB::WriteFileSizeL(TUint aSize) |
596 void CFatFileCB::WriteFileSizeL(TUint aSize) |
587 { |
597 { |
588 __PRINT(_L("CFatFileCB::WriteFileSizeL")); |
598 __PRINT(_L("CFatFileCB::WriteFileSizeL")); |
589 TEntryPos entryPos=iFileDirPos; |
599 TEntryPos entryPos=iFileDirPos; |
590 entryPos.iPos+=_FOFF(SFatDirEntry,iSize); |
600 entryPos.iPos+=_FOFF(SFatDirEntry,iSize); |
591 TPtrC8 size((TUint8*)&aSize,sizeof(TUint)); |
601 TPtrC8 size((TUint8*)&aSize,sizeof(TUint)); |
592 |
602 |
593 //-- use directory cache when dealing with directories |
603 //-- use directory cache when dealing with directories |
594 FatMount().DirWriteL(entryPos,size); |
604 FatMount().DirWriteL(entryPos,size); |
595 iFileSizeModified=EFalse; |
605 iFileSizeModified=EFalse; |
596 } |
606 } |
597 |
607 |
598 //----------------------------------------------------------------------------- |
608 //----------------------------------------------------------------------------- |
599 /** |
609 /** |
600 Flush file size, attributes, time etc. to the media. |
610 Flush file size, attributes, time etc. to the media. |
601 It doesn't matter if whole directory entry is being written of only part of it. Anyway, a single DOS |
611 It doesn't matter if whole directory entry is being written of only part of it. Anyway, a single DOS |
602 dir. entry always fits into 1 sector. |
612 dir. entry always fits into 1 sector. |
603 */ |
613 */ |
604 void CFatFileCB::FlushDataL() |
614 void CFatFileCB::FlushDataL() |
605 { |
615 { |
606 __PRINT(_L("CFatFileCB::FlushDataL")); |
616 __PRINT(_L("CFatFileCB::FlushDataL")); |
607 FlushAllL(); |
617 FlushAllL(); |
608 } |
618 } |
609 |
619 |
610 //----------------------------------------------------------------------------- |
620 //----------------------------------------------------------------------------- |
611 /** |
621 /** |
612 Flush the fide directory entry data: files size, attributes, time etc. |
622 Flush the fide directory entry data: files size, attributes, time etc. |
613 */ |
623 */ |
614 void CFatFileCB::FlushAllL() |
624 void CFatFileCB::FlushAllL() |
615 { |
625 { |
616 __PRINT(_L("CFatFileCB::FlushAllL()")); |
626 __PRINT(_L("CFatFileCB::FlushAllL()")); |
617 |
627 |
618 if (Mount().IsCurrentMount()==EFalse) |
628 if (Mount().IsCurrentMount()==EFalse) |
619 User::Leave(KErrDisMounted); |
629 User::Leave(KErrDisMounted); |
620 |
630 |
621 FatMount().CheckStateConsistentL(); |
631 FatMount().CheckStateConsistentL(); |
622 FatMount().CheckWritableL(); |
632 FatMount().CheckWritableL(); |
623 |
633 |
624 TFatDirEntry entry; |
634 TFatDirEntry entry; |
625 FatMount().ReadDirEntryL(iFileDirPos,entry); |
635 FatMount().ReadDirEntryL(iFileDirPos,entry); |
626 __ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt)); |
636 __ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt)); |
627 entry.SetAttributes(iAtt&KEntryAttMaskSupported); |
637 entry.SetAttributes(iAtt&KEntryAttMaskSupported); |
628 entry.SetSize(Size()); |
638 entry.SetSize(Size()); |
629 entry.SetTime(iModified, FatMount().TimeOffset()); |
639 entry.SetTime(iModified, FatMount().TimeOffset()); |
630 entry.SetStartCluster(iStartCluster); |
640 entry.SetStartCluster(iStartCluster); |
631 |
641 |
632 TBool setNotify = FatMount().GetNotifyUser(); |
642 TBool setNotify = FatMount().GetNotifyUser(); |
633 if(setNotify) |
643 if(setNotify) |
634 { |
644 { |
635 FatMount().SetNotifyOff(); // do not launch a notifier |
645 FatMount().SetNotifyOff(); // do not launch a notifier |
636 } |
646 } |
637 |
647 |
638 TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry)); |
648 TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry)); |
639 |
649 |
640 if(setNotify) |
650 if(setNotify) |
641 { |
651 { |
642 FatMount().SetNotifyOn(); |
652 FatMount().SetNotifyOn(); |
643 } |
653 } |
644 |
654 |
645 User::LeaveIfError(ret); |
655 User::LeaveIfError(ret); |
646 iAtt&=(~KEntryAttModified); |
656 iAtt&=(~KEntryAttModified); |
647 iFileSizeModified=EFalse; |
657 iFileSizeModified=EFalse; |
648 } |
658 } |
649 |
659 |
650 //----------------------------------------------------------------------------- |
660 //----------------------------------------------------------------------------- |
651 |
661 |
652 /** |
662 /** |
653 Rename already opened file. |
663 Rename already opened file. |
654 @param aNewName new file name; all trailing dots from the name will be removed |
664 @param aNewName new file name; all trailing dots from the name will be removed |
655 */ |
665 */ |
656 void CFatFileCB::RenameL(const TDesC& aNewName) |
666 void CFatFileCB::RenameL(const TDesC& aNewName) |
657 { |
667 { |
658 __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName); |
668 __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName); |
659 |
669 |
660 FatMount().CheckStateConsistentL(); |
670 FatMount().CheckStateConsistentL(); |
661 FatMount().CheckWritableL(); |
671 FatMount().CheckWritableL(); |
662 |
672 |
663 const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name |
673 const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name |
664 |
674 |
665 |
675 |
666 FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos); |
676 FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos); |
667 |
677 |
668 AllocBufferL(iFileName, fileName); |
678 AllocBufferL(iFileName, fileName); |
669 |
679 |
670 if(!FatMount().IsRuggedFSys()) |
680 if(!FatMount().IsRuggedFSys()) |
671 FAT().FlushL(); |
681 FAT().FlushL(); |
672 } |
682 } |
673 |
683 |
674 |
684 |
675 //*********************************************************** |
685 //*********************************************************** |
676 //* BlockMap interface |
686 //* BlockMap interface |
677 //*********************************************************** |
687 //*********************************************************** |
678 |
688 |
679 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos) |
689 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos) |
680 // |
690 // |
681 // Retrieves the block map of a given section of the file, in the FAT file system. |
691 // Retrieves the block map of a given section of the file, in the FAT file system. |
682 // |
692 // |
683 { |
693 { |
684 __PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos); |
694 __PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos); |
685 |
695 |
686 if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) ) |
696 if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) ) |
687 return KErrNotSupported; |
697 return KErrNotSupported; |
688 |
698 |
689 TUint startPos = I64LOW(aStartPos); |
699 TUint startPos = I64LOW(aStartPos); |
690 TUint endPos = I64LOW(aEndPos); |
700 TUint endPos = I64LOW(aEndPos); |
691 |
701 |
692 // aEndPos will always be >=0 at this point |
702 // aEndPos will always be >=0 at this point |
693 const TUint length = endPos - startPos; |
703 const TUint length = endPos - startPos; |
694 |
704 |
695 // Store the position of cluster zero in aInfo |
705 // Store the position of cluster zero in aInfo |
696 CFatMountCB& fatMount = FatMount(); |
706 CFatMountCB& fatMount = FatMount(); |
697 |
707 |
698 TInt drvNo=-1; |
708 TInt drvNo=-1; |
699 TBusLocalDrive* locDrv; |
709 TBusLocalDrive* locDrv; |
700 if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives)) |
710 if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives)) |
701 aInfo.iLocalDriveNumber=drvNo; |
711 aInfo.iLocalDriveNumber=drvNo; |
702 else |
712 else |
703 return KErrNotSupported; |
713 return KErrNotSupported; |
704 |
714 |
705 // Fetch the address of cluster 0 |
715 // Fetch the address of cluster 0 |
706 aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytes(KFirstClusterNum); |
716 aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytes(KFirstClusterNum); |
707 |
717 |
708 TRAPD(r, CheckPosL(startPos)); |
718 TRAPD(r, CheckPosL(startPos)); |
709 if (r != KErrNone) |
719 if (r != KErrNone) |
710 return r; |
720 return r; |
711 |
721 |
712 aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos); |
722 aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos); |
713 aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2(); |
723 aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2(); |
714 const TUint myStartPos = iCurrentPos.iPos; |
724 const TUint myStartPos = iCurrentPos.iPos; |
715 if ( myStartPos + length > (TUint)Size()) |
725 if ( myStartPos + length > (TUint)Size()) |
716 return KErrArgument; |
726 return KErrArgument; |
717 |
727 |
718 TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo)); |
728 TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo)); |
719 if (r != KErrNone) |
729 if (r != KErrNone) |
720 return r; |
730 return r; |
721 |
731 |
722 aStartPos = iCurrentPos.iPos; |
732 aStartPos = iCurrentPos.iPos; |
723 if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length))) |
733 if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length))) |
724 return KErrCompletion; |
734 return KErrCompletion; |
725 else |
735 else |
726 return KErrNone; |
736 return KErrNone; |
727 } |
737 } |
728 |
738 |
729 |
739 |
730 |
740 |
731 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
741 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
732 { |
742 { |
733 switch(aInterfaceId) |
743 switch(aInterfaceId) |
734 { |
744 { |
735 case EExtendedFileInterface: |
745 case EExtendedFileInterface: |
736 ((CFileCB::MExtendedFileInterface*&) aInterface) = this; |
746 ((CFileCB::MExtendedFileInterface*&) aInterface) = this; |
737 return KErrNone; |
747 return KErrNone; |
738 |
748 |
739 case EBlockMapInterface: |
749 case EBlockMapInterface: |
740 aInterface = (CFileCB::MBlockMapInterface*) this; |
750 aInterface = (CFileCB::MBlockMapInterface*) this; |
741 return KErrNone; |
751 return KErrNone; |
742 |
752 |
743 case EGetLocalDrive: |
753 case EGetLocalDrive: |
744 return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface); |
754 return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface); |
745 |
755 |
746 default: |
756 default: |
747 return CFileCB::GetInterface(aInterfaceId,aInterface,aInput); |
757 return CFileCB::GetInterface(aInterfaceId,aInterface,aInput); |
748 } |
758 } |
749 } |
759 } |
750 |
760 |
751 |
761 |
752 |
762 |
753 |
763 |
754 /** |
764 /** |
755 Overwrites file's start cluster (iStartCluster) in its directory entry. |
765 Overwrites file's start cluster (iStartCluster) in its directory entry. |
756 */ |
766 */ |
757 void CFatFileCB::FlushStartClusterL() |
767 void CFatFileCB::FlushStartClusterL() |
758 { |
768 { |
759 __PRINT(_L("CFatFileCB::FlushStartClusterL")); |
769 __PRINT(_L("CFatFileCB::FlushStartClusterL")); |
760 |
770 |
761 CFatMountCB& mount = FatMount(); |
771 CFatMountCB& mount = FatMount(); |
762 TFatDirEntry dirEntry; |
772 TFatDirEntry dirEntry; |
763 |
773 |
764 mount.ReadDirEntryL(iFileDirPos, dirEntry); //-- read this file's dir. entry |
774 mount.ReadDirEntryL(iFileDirPos, dirEntry); //-- read this file's dir. entry |
765 dirEntry.SetStartCluster(iStartCluster); //-- set new start cluster |
775 dirEntry.SetStartCluster(iStartCluster); //-- set new start cluster |
766 mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back |
776 mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back |
767 } |
777 } |
768 |
778 |
769 |
779 |
770 |
780 |
771 |
781 |
772 |
782 |