40 {//-- do some finalisation work if CMountCB is valid |
40 {//-- do some finalisation work if CMountCB is valid |
41 if(FileAttModified()) |
41 if(FileAttModified()) |
42 { |
42 { |
43 IndicateFileTimeModified(ETrue); //-- this will force writing file modification time to the media on Flush |
43 IndicateFileTimeModified(ETrue); //-- this will force writing file modification time to the media on Flush |
44 TRAP_IGNORE(FlushAllL()); |
44 TRAP_IGNORE(FlushAllL()); |
45 } |
45 } |
46 } |
46 } |
47 |
47 |
48 delete[] iSeekIndex; |
48 delete[] iSeekIndex; |
49 } |
49 } |
50 |
50 |
51 |
51 |
52 void CFatFileCB::CreateSeekIndex() |
52 void CFatFileCB::CreateSeekIndex() |
53 // |
53 // |
54 // Create a seek index |
54 // Create a seek index |
55 // |
55 // |
56 { |
56 { |
57 |
57 |
58 iSeekIndex = new TUint32[KSeekIndexSize]; |
58 iSeekIndex = new TUint32[KSeekIndexSize]; |
59 if (iSeekIndex == NULL) |
59 if (iSeekIndex == NULL) |
60 return; |
60 return; |
61 |
61 |
62 Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize); |
62 Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize); |
63 |
63 |
64 iSeekIndexSize=CalcSeekIndexSize(FCB_FileSize()); |
64 iSeekIndexSize=CalcSeekIndexSize(FCB_FileSize()); |
65 } |
65 } |
66 |
66 |
67 TInt CFatFileCB::SeekToPosition(TUint aNewRelCluster, TUint aClusterOffset) |
67 TInt CFatFileCB::SeekToPosition(TUint aNewRelCluster, TUint aClusterOffset) |
68 // |
68 // |
69 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster |
69 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster |
70 // Return aNewRelCluster-aCurrentPos.iCluster |
70 // Return aNewRelCluster-aCurrentPos.iCluster |
71 // |
71 // |
72 { |
72 { |
73 TInt clusterOffset=aClusterOffset; |
73 TInt clusterOffset=aClusterOffset; |
74 TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1; |
74 TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1; |
75 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
75 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
76 |
76 |
77 while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0) |
77 while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0) |
78 { |
78 { |
79 seekPos--; |
79 seekPos--; |
80 clusterOffset--; |
80 clusterOffset--; |
81 } |
81 } |
82 if (clusterOffset==0) // Counted back to the current cluster |
82 if (clusterOffset==0) // Counted back to the current cluster |
83 return(aClusterOffset); |
83 return(aClusterOffset); |
84 if (seekPos<0) |
84 if (seekPos<0) |
85 { |
85 { |
86 iCurrentPos.iCluster=FCB_StartCluster(); |
86 iCurrentPos.iCluster=FCB_StartCluster(); |
87 return(aNewRelCluster); |
87 return(aNewRelCluster); |
88 } |
88 } |
89 |
89 |
90 iCurrentPos.iCluster=iSeekIndex[seekPos]; |
90 iCurrentPos.iCluster=iSeekIndex[seekPos]; |
91 return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize)); |
91 return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize)); |
92 } |
92 } |
93 |
93 |
94 void CFatFileCB::SetSeekIndexValueL(TUint aRelCluster, TUint aStoredCluster) |
94 void CFatFileCB::SetSeekIndexValueL(TUint aRelCluster, TUint aStoredCluster) |
95 // |
95 // |
96 // Sets a value in the seekindex |
96 // Sets a value in the seekindex |
97 // |
97 // |
98 { |
98 { |
99 |
99 |
100 TInt seekPos=(aRelCluster>>iSeekIndexSize)-1; |
100 TInt seekPos=(aRelCluster>>iSeekIndexSize)-1; |
101 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
101 __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall)); |
102 __ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2)); |
102 __ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2)); |
103 iSeekIndex[seekPos] = aStoredCluster; |
103 iSeekIndex[seekPos] = aStoredCluster; |
104 } |
104 } |
105 |
105 |
106 void CFatFileCB::CheckPosL(TUint aPos) |
106 void CFatFileCB::CheckPosL(TUint aPos) |
107 // |
107 // |
108 // Check that the file is positioned correctly. |
108 // Check that the file is positioned correctly. |
109 // If aPos<currentPos attempt to guess the new position. |
109 // If aPos<currentPos attempt to guess the new position. |
110 // |
110 // |
111 { |
111 { |
112 __PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos); |
112 __PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos); |
113 if (aPos==iCurrentPos.iPos) |
113 if (aPos==iCurrentPos.iPos) |
114 return; |
114 return; |
115 __ASSERT_DEBUG(aPos <= FCB_FileSize(), Fault(EFatFilePosBeyondEnd)); |
115 __ASSERT_DEBUG(aPos <= FCB_FileSize(), Fault(EFatFilePosBeyondEnd)); |
116 |
116 |
117 TUint newRelCluster=aPos>>ClusterSizeLog2(); |
117 TUint newRelCluster=aPos>>ClusterSizeLog2(); |
118 if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) ) |
118 if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) ) |
119 newRelCluster--; |
119 newRelCluster--; |
120 TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2(); |
120 TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2(); |
121 |
121 |
122 if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) ) |
122 if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) ) |
123 oldRelCluster--; |
123 oldRelCluster--; |
124 |
124 |
125 TInt clusterOffset=newRelCluster-oldRelCluster; |
125 TInt clusterOffset=newRelCluster-oldRelCluster; |
126 TUint32 oldCluster=iCurrentPos.iCluster; |
126 TUint32 oldCluster=iCurrentPos.iCluster; |
127 |
127 |
128 iCurrentPos.iPos=aPos; |
128 iCurrentPos.iPos=aPos; |
129 if (clusterOffset==0) |
129 if (clusterOffset==0) |
130 return; |
130 return; |
131 TInt seekOffset=clusterOffset; |
131 TInt seekOffset=clusterOffset; |
132 if (iSeekIndex!=NULL) |
132 if (iSeekIndex!=NULL) |
133 { // Can alter iCurrentPos.iCluster |
133 { // Can alter iCurrentPos.iCluster |
134 seekOffset=SeekToPosition(newRelCluster,seekOffset); |
134 seekOffset=SeekToPosition(newRelCluster,seekOffset); |
135 if (seekOffset==0) |
135 if (seekOffset==0) |
136 return; |
136 return; |
137 } |
137 } |
138 if (clusterOffset==-1 && seekOffset!=1) |
138 if (clusterOffset==-1 && seekOffset!=1) |
139 { // Check previous cluster |
139 { // Check previous cluster |
140 TUint32 cluster=oldCluster-1; |
140 TUint32 cluster=oldCluster-1; |
141 if (FAT().GetNextClusterL(cluster) && cluster==oldCluster) |
141 if (FAT().GetNextClusterL(cluster) && cluster==oldCluster) |
142 { |
142 { |
143 iCurrentPos.iCluster=oldCluster-1; |
143 iCurrentPos.iCluster=oldCluster-1; |
144 return; |
144 return; |
145 } |
145 } |
146 } |
146 } |
147 if (seekOffset<0) |
147 if (seekOffset<0) |
148 { |
148 { |
149 seekOffset=newRelCluster; |
149 seekOffset=newRelCluster; |
150 iCurrentPos.iCluster=FCB_StartCluster(); |
150 iCurrentPos.iCluster=FCB_StartCluster(); |
151 } |
151 } |
152 while (seekOffset--) |
152 while (seekOffset--) |
153 { |
153 { |
154 if (!FAT().GetNextClusterL(iCurrentPos.iCluster)) |
154 if (!FAT().GetNextClusterL(iCurrentPos.iCluster)) |
155 { |
155 { |
156 __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1")); |
156 __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1")); |
157 User::Leave(KErrCorrupt); |
157 User::Leave(KErrCorrupt); |
158 } |
158 } |
159 TInt cluster=newRelCluster-seekOffset; |
159 TInt cluster=newRelCluster-seekOffset; |
160 if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster) |
160 if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster) |
161 SetSeekIndexValueL(cluster,iCurrentPos.iCluster); |
161 SetSeekIndexValueL(cluster,iCurrentPos.iCluster); |
162 } |
162 } |
163 } |
163 } |
164 |
164 |
165 //----------------------------------------------------------------------------- |
165 //----------------------------------------------------------------------------- |
166 /** |
166 /** |
167 Initialize FileCB from file's entry data. |
167 Initialize FileCB from file's entry data. |
168 |
168 |
169 @param aFatDirEntry this file DOS dir entry. |
169 @param aFatDirEntry this file DOS dir entry. |
170 @param aFileDosEntryPos this file DOS entry dir. iterator in the parent directory. |
170 @param aFileDosEntryPos this file DOS entry dir. iterator in the parent directory. |
171 */ |
171 */ |
172 void CFatFileCB::SetupL(const TFatDirEntry& aFatDirEntry, const TEntryPos& aFileDosEntryPos) |
172 void CFatFileCB::SetupL(const TFatDirEntry& aFatDirEntry, const TEntryPos& aFileDosEntryPos) |
173 { |
173 { |
174 __PRINT1(_L("CFatFileCB::SetupL[0x%x]"), this); |
174 __PRINT1(_L("CFatFileCB::SetupL[0x%x]"), this); |
175 |
175 |
176 |
176 |
177 //-- set up a file control block |
177 //-- set up a file control block |
178 iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry); |
178 iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry); |
179 iCurrentPos.iPos=0; |
179 iCurrentPos.iPos=0; |
180 |
180 |
181 SetAtt(aFatDirEntry.Attributes()); |
181 SetAtt(aFatDirEntry.Attributes()); |
182 SetModified(aFatDirEntry.Time(FatMount().TimeOffset())); |
182 SetModified(aFatDirEntry.Time(FatMount().TimeOffset())); |
183 |
183 |
184 FCB_SetStartCluster(iCurrentPos.iCluster); |
184 FCB_SetStartCluster(iCurrentPos.iCluster); |
185 FCB_SetFileSize(aFatDirEntry.Size()); |
185 FCB_SetFileSize(aFatDirEntry.Size()); |
186 |
186 |
187 iFileDosEntryPos = aFileDosEntryPos; |
187 iFileDosEntryPos = aFileDosEntryPos; |
188 |
188 |
189 SetMaxSupportedSize(KMaxSupportedFatFileSize); |
189 SetMaxSupportedSize(KMaxSupportedFatFileSize); |
190 |
190 |
191 //-- create seek index |
191 //-- create seek index |
192 ASSERT(!iSeekIndex); |
192 ASSERT(!iSeekIndex); |
255 |
255 |
256 @leave on media read error |
256 @leave on media read error |
257 |
257 |
258 */ |
258 */ |
259 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset) |
259 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset) |
260 { |
260 { |
261 __PRINT3(_L("CFatFileCB::WriteL[0x%x] pos=%LU len=%d"), this, aPos, aLength); |
261 __PRINT3(_L("CFatFileCB::WriteL[0x%x] pos=%LU len=%d"), this, aPos, aLength); |
262 |
262 |
263 // FAT supports 32 bits only for file size |
263 // FAT supports 32 bits only for file size |
264 TUint64 endPos = aPos + aLength; |
264 TUint64 endPos = aPos + aLength; |
265 if(endPos > KMaxSupportedFatFileSize) |
265 if(endPos > KMaxSupportedFatFileSize) |
266 User::Leave(KErrNotSupported); |
266 User::Leave(KErrNotSupported); |
267 |
267 |
268 FatMount().CheckStateConsistentL(); |
268 FatMount().CheckStateConsistentL(); |
269 FatMount().CheckWritableL(); |
269 FatMount().CheckWritableL(); |
270 const TUint pos = I64LOW(aPos); |
270 const TUint pos = I64LOW(aPos); |
271 CheckPosL(pos); |
271 CheckPosL(pos); |
272 |
272 |
273 const TUint startCluster = FCB_StartCluster(); |
273 const TUint startCluster = FCB_StartCluster(); |
274 const TUint length = (TUint)aLength; |
274 const TUint length = (TUint)aLength; |
275 |
275 |
276 endPos = iCurrentPos.iPos + length; |
276 endPos = iCurrentPos.iPos + length; |
277 if ((endPos > FCB_FileSize()) || |
277 if ((endPos > FCB_FileSize()) || |
278 (iCurrentPos.iPos > endPos) ) // Overflow condition |
278 (iCurrentPos.iPos > endPos) ) // Overflow condition |
279 DoSetSizeL(iCurrentPos.iPos+length,EFalse); |
279 DoSetSizeL(iCurrentPos.iPos+length,EFalse); |
280 |
280 |
281 TUint startPos=iCurrentPos.iPos; |
281 TUint startPos=iCurrentPos.iPos; |
282 TUint badcluster=0; |
282 TUint badcluster=0; |
283 TUint goodcluster=0; |
283 TUint goodcluster=0; |
284 |
284 |
285 TUint flag = DirectIOMode(aMessage) ? RLocalDrive::ELocDrvDirectIO : 0; |
285 TUint flag = DirectIOMode(aMessage) ? RLocalDrive::ELocDrvDirectIO : 0; |
286 |
286 |
287 TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster, flag)); |
287 TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster, flag)); |
288 |
288 |
289 if (ret == KErrCorrupt || ret == KErrDied) |
289 if (ret == KErrCorrupt || ret == KErrDied) |
290 { |
290 { |
291 if(startCluster == 0) |
291 if(startCluster == 0) |
292 { //Empty File, revert all the clusters allocated. |
292 { //Empty File, revert all the clusters allocated. |
293 const TUint32 cluster = FCB_StartCluster(); |
293 const TUint32 cluster = FCB_StartCluster(); |
294 FCB_SetStartCluster(0); |
294 FCB_SetStartCluster(0); |
295 FCB_SetFileSize(0); |
295 FCB_SetFileSize(0); |
296 IndicateFileSizeModified(ETrue); |
296 IndicateFileSizeModified(ETrue); |
297 |
297 |
298 FlushAllL(); |
298 FlushAllL(); |
299 |
299 |
300 iCurrentPos.iCluster = 0; |
300 iCurrentPos.iCluster = 0; |
301 iCurrentPos.iPos = 0; |
301 iCurrentPos.iPos = 0; |
302 |
302 |
303 FAT().FreeClusterListL(cluster); |
303 FAT().FreeClusterListL(cluster); |
304 FAT().FlushL(); |
304 FAT().FlushL(); |
305 } |
305 } |
306 else |
306 else |
307 { //Calculate the clusters required based on file size, revert extra clusters if allocated. |
307 { //Calculate the clusters required based on file size, revert extra clusters if allocated. |
308 const TUint curSize = FCB_FileSize(); |
308 const TUint curSize = FCB_FileSize(); |
309 TUint ClustersNeeded = curSize >> ClusterSizeLog2(); |
309 TUint ClustersNeeded = curSize >> ClusterSizeLog2(); |
310 if(curSize > (ClustersNeeded << ClusterSizeLog2())) |
310 if(curSize > (ClustersNeeded << ClusterSizeLog2())) |
311 { |
311 { |
312 ClustersNeeded++; |
312 ClustersNeeded++; |
313 } |
313 } |
314 |
314 |
315 TUint32 cluster = FCB_StartCluster(); |
315 TUint32 cluster = FCB_StartCluster(); |
316 while(--ClustersNeeded) |
316 while(--ClustersNeeded) |
317 { |
317 { |
318 FAT().GetNextClusterL(cluster); |
318 FAT().GetNextClusterL(cluster); |
319 } |
319 } |
320 |
320 |
321 iCurrentPos.iCluster = cluster; |
321 iCurrentPos.iCluster = cluster; |
322 |
322 |
323 if (FAT().GetNextClusterL(cluster)) |
323 if (FAT().GetNextClusterL(cluster)) |
324 { |
324 { |
325 FAT().FreeClusterListL(cluster); |
325 FAT().FreeClusterListL(cluster); |
326 } |
326 } |
327 |
327 |
328 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
328 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
329 FAT().FlushL(); |
329 FAT().FlushL(); |
330 } |
330 } |
331 } |
331 } |
332 |
332 |
333 User::LeaveIfError(ret); |
333 User::LeaveIfError(ret); |
334 |
334 |
335 if(badcluster != 0) |
335 if(badcluster != 0) |
336 { |
336 { |
337 if(FCB_StartCluster() == badcluster) |
337 if(FCB_StartCluster() == badcluster) |
338 { |
338 { |
339 FCB_SetStartCluster(goodcluster); |
339 FCB_SetStartCluster(goodcluster); |
340 FlushStartClusterL(); |
340 FlushStartClusterL(); |
341 } |
341 } |
342 else |
342 else |
343 { |
343 { |
344 TUint32 aCluster = FCB_StartCluster(); |
344 TUint32 aCluster = FCB_StartCluster(); |
345 do |
345 do |
346 { |
346 { |
347 if((TUint)badcluster == FAT().ReadL(aCluster)) |
347 if((TUint)badcluster == FAT().ReadL(aCluster)) |
348 { |
348 { |
349 FAT().WriteL(aCluster, goodcluster); |
349 FAT().WriteL(aCluster, goodcluster); |
350 FAT().FlushL(); |
350 FAT().FlushL(); |
351 break; |
351 break; |
352 } |
352 } |
353 } |
353 } |
354 while(FAT().GetNextClusterL(aCluster)); |
354 while(FAT().GetNextClusterL(aCluster)); |
355 } |
355 } |
356 } |
356 } |
357 aLength=iCurrentPos.iPos-startPos; |
357 aLength=iCurrentPos.iPos-startPos; |
358 |
358 |
359 if(FatMount().IsRuggedFSys() && pos+(TUint)aLength > FCB_FileSize()) |
359 if(!IsSequentialMode() && FatMount().IsRuggedFSys() && pos+(TUint)aLength > FCB_FileSize()) |
360 { |
360 { |
361 WriteFileSizeL(pos+aLength); |
361 WriteFileSizeL(pos+aLength); |
362 } |
362 } |
363 |
363 |
364 } |
364 } |
365 |
365 |
366 |
366 |
367 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage) |
367 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage) |
368 { |
368 { |
369 WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0); |
369 WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0); |
370 } |
370 } |
371 |
|
372 |
371 |
373 |
372 |
374 //----------------------------------------------------------------------------- |
373 //----------------------------------------------------------------------------- |
375 |
374 |
376 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize) |
375 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize) |
377 // |
376 // |
378 // Resize the seek index to accomodate a larger or smaller filesize |
377 // Resize the seek index to accomodate a larger or smaller filesize |
379 // Assumes KSeekIndexSize is a power of 2. |
378 // Assumes KSeekIndexSize is a power of 2. |
380 // |
379 // |
381 { |
380 { |
382 |
381 |
383 TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult); |
382 TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult); |
384 |
383 |
385 |
384 |
386 TInt index=0; |
385 TInt index=0; |
387 TInt indexEnd=KSeekIndexSize; |
386 TInt indexEnd=KSeekIndexSize; |
388 TInt newValEnd=maxNewIndex; |
387 TInt newValEnd=maxNewIndex; |
389 |
388 |
390 if (iSeekIndexSize<aNewMult) |
389 if (iSeekIndexSize<aNewMult) |
391 { |
390 { |
392 TInt newVal=index; |
391 TInt newVal=index; |
393 TInt step=1<<(aNewMult-iSeekIndexSize); |
392 TInt step=1<<(aNewMult-iSeekIndexSize); |
394 index+=step-1; |
393 index+=step-1; |
395 while(index<indexEnd && newVal<newValEnd) |
394 while(index<indexEnd && newVal<newValEnd) |
396 { |
395 { |
397 iSeekIndex[newVal] = iSeekIndex[index]; |
396 iSeekIndex[newVal] = iSeekIndex[index]; |
398 newVal++; |
397 newVal++; |
399 index+=step; |
398 index+=step; |
400 } |
399 } |
401 while(newVal<indexEnd) |
400 while(newVal<indexEnd) |
402 iSeekIndex[newVal++] = 0; |
401 iSeekIndex[newVal++] = 0; |
403 } |
402 } |
404 else |
403 else |
405 { |
404 { |
406 TInt diffSize = iSeekIndexSize-aNewMult; |
405 TInt diffSize = iSeekIndexSize-aNewMult; |
407 TInt oldVal=(KSeekIndexSize>>diffSize) - 1; |
406 TInt oldVal=(KSeekIndexSize>>diffSize) - 1; |
408 TInt newVal=indexEnd-1; |
407 TInt newVal=indexEnd-1; |
409 TInt skip=(1<<diffSize)-1; |
408 TInt skip=(1<<diffSize)-1; |
410 |
409 |
411 if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2) |
410 if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2) |
412 { |
411 { |
413 ClearIndex(0); //-- Invalidate every entry. |
412 ClearIndex(0); //-- Invalidate every entry. |
414 } |
413 } |
415 else |
414 else |
416 { |
415 { |
417 while(newVal>=index) |
416 while(newVal>=index) |
418 { |
417 { |
419 |
418 |
420 iSeekIndex[newVal--] = iSeekIndex[oldVal--]; |
419 iSeekIndex[newVal--] = iSeekIndex[oldVal--]; |
421 |
420 |
422 |
421 |
423 for(TInt i=skip;i>0;i--) |
422 for(TInt i=skip;i>0;i--) |
424 { |
423 { |
425 iSeekIndex[newVal--] = 0; |
424 iSeekIndex[newVal--] = 0; |
426 |
425 |
427 } |
426 } |
428 } |
427 } |
429 } |
428 } |
430 } |
429 } |
431 iSeekIndexSize=aNewMult; |
430 iSeekIndexSize=aNewMult; |
432 } |
431 } |
433 |
432 |
434 |
433 |
435 /** |
434 /** |
436 Zero freed clusters in the index |
435 Zero freed clusters in the index |
437 |
436 |
438 @param aNewSize new size of the file that the index corresponds to. |
437 @param aNewSize new size of the file that the index corresponds to. |
439 if = 0 all existing index will be zero filled |
438 if = 0 all existing index will be zero filled |
440 */ |
439 */ |
441 void CFatFileCB::ClearIndex(TUint aNewSize) |
440 void CFatFileCB::ClearIndex(TUint aNewSize) |
442 { |
441 { |
443 |
442 |
444 if (!iSeekIndex) |
443 if (!iSeekIndex) |
445 return; |
444 return; |
446 |
445 |
447 if(aNewSize==0) |
446 if(aNewSize==0) |
448 { |
447 { |
449 //-- zero fill all the array |
448 //-- zero fill all the array |
450 Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32)); |
449 Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32)); |
451 return; |
450 return; |
452 } |
451 } |
453 |
452 |
454 // Files that fill up a cluster exactly do not have a trailing empty |
453 // Files that fill up a cluster exactly do not have a trailing empty |
455 // cluster. So the entry for that position must also be invalidated |
454 // cluster. So the entry for that position must also be invalidated |
456 aNewSize--; |
455 aNewSize--; |
457 TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2()); |
456 TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2()); |
458 |
457 |
459 TInt indexLen=KSeekIndexSize-firstInvalidIndex; |
458 TInt indexLen=KSeekIndexSize-firstInvalidIndex; |
460 |
459 |
461 Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32)); |
460 Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32)); |
462 } |
461 } |
463 |
462 |
464 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize) |
463 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize) |
465 // |
464 // |
466 // Find the nearest power of 2 > aSize |
465 // Find the nearest power of 2 > aSize |
467 // |
466 // |
468 { |
467 { |
469 TInt count = 0; |
468 TInt count = 0; |
470 const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128 |
469 const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128 |
471 if (aSize<=indexSize) |
470 if (aSize<=indexSize) |
472 return(count); |
471 return(count); |
473 |
472 |
474 while((aSize>>=1)>0) |
473 while((aSize>>=1)>0) |
475 { |
474 { |
476 count++; |
475 count++; |
477 } |
476 } |
478 return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1); |
477 return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1); |
479 } |
478 } |
480 |
479 |
481 //----------------------------------------------------------------------------- |
480 //----------------------------------------------------------------------------- |
482 /** |
481 /** |
483 Set file size. |
482 Set file size. |
484 @param aSize new file size. |
483 @param aSize new file size. |
485 */ |
484 */ |
486 void CFatFileCB::SetSizeL(TInt64 aSize) |
485 void CFatFileCB::SetSizeL(TInt64 aSize) |
487 { |
486 { |
488 __PRINT2(_L("CFatFileCB::SetSizeL[0x%x] sz=%LU"), this, aSize); |
487 __PRINT2(_L("CFatFileCB::SetSizeL[0x%x] sz=%LU"), this, aSize); |
489 |
488 |
490 //-- max. file size for FAT is 4GB-1 |
489 //-- max. file size for FAT is 4GB-1 |
491 if (I64HIGH(aSize)) |
490 if (I64HIGH(aSize)) |
492 User::Leave(KErrNotSupported); |
491 User::Leave(KErrNotSupported); |
493 |
492 |
494 DoSetSizeL(I64LOW(aSize), FatMount().IsRuggedFSys()); |
493 DoSetSizeL(I64LOW(aSize), FatMount().IsRuggedFSys()); |
495 } |
494 } |
496 |
495 |
497 |
496 |
498 void CFatFileCB::SetSizeL(TInt aSize) |
497 void CFatFileCB::SetSizeL(TInt aSize) |
499 { |
498 { |
500 SetSizeL(TInt64(aSize)); |
499 SetSizeL(TInt64(aSize)); |
501 } |
500 } |
502 |
501 |
503 //----------------------------------------------------------------------------- |
502 //----------------------------------------------------------------------------- |
504 /** |
503 /** |
505 Shrink file to zero size. |
504 Shrink file to zero size. |
506 */ |
505 */ |
507 void CFatFileCB::DoShrinkFileToZeroSizeL() |
506 void CFatFileCB::DoShrinkFileToZeroSizeL() |
508 { |
507 { |
509 ASSERT(FCB_FileSize()); |
508 ASSERT(FCB_FileSize()); |
510 ASSERT(FileSizeModified()); |
509 ASSERT(FileSizeModified()); |
511 |
510 |
512 ClearIndex(0); //-- clear seek index array |
511 ClearIndex(0); // Clear seek index array |
513 |
512 |
514 //-- update file dir. entry |
513 //-- update file dir. entry |
515 const TUint32 cluster = FCB_StartCluster(); |
514 const TUint32 cluster = FCB_StartCluster(); |
516 FCB_SetStartCluster(0); |
515 FCB_SetStartCluster(0); |
517 FCB_SetFileSize(0); |
516 FCB_SetFileSize(0); |
518 FlushAllL(); |
517 FlushAllL(); |
519 |
518 |
520 //-- free cluster list. |
519 //-- free cluster list. |
521 CheckPosL(0); |
520 CheckPosL(0); |
522 FAT().FreeClusterListL(cluster); |
521 FAT().FreeClusterListL(cluster); |
523 FAT().FlushL(); |
522 FAT().FlushL(); |
524 } |
523 } |
525 |
524 |
526 //----------------------------------------------------------------------------- |
525 //----------------------------------------------------------------------------- |
527 /* |
526 /* |
528 Shrink file to smaller size, but > 0 |
527 Shrink file to smaller size, but > 0 |
529 |
528 |
530 @param aNewSize new file size |
529 @param aNewSize new file size |
531 @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed |
530 @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed |
532 */ |
531 */ |
533 void CFatFileCB::DoShrinkFileL(TUint32 aNewSize, TBool aForceCachesFlush) |
532 void CFatFileCB::DoShrinkFileL(TUint32 aNewSize, TBool aForceCachesFlush) |
534 { |
533 { |
535 ASSERT(FileSizeModified()); |
534 ASSERT(FileSizeModified()); |
536 ASSERT(FCB_FileSize() > aNewSize && aNewSize); |
535 ASSERT(FCB_FileSize() > aNewSize && aNewSize); |
537 |
536 |
538 if(aForceCachesFlush) |
537 if(aForceCachesFlush) |
539 WriteFileSizeL(aNewSize); //-- write file size directly to its dir. entry |
538 WriteFileSizeL(aNewSize); //-- write file size directly to its dir. entry |
540 |
539 |
541 CheckPosL(aNewSize); |
540 CheckPosL(aNewSize); |
542 |
541 |
543 TUint32 cluster=iCurrentPos.iCluster; |
542 TUint32 cluster=iCurrentPos.iCluster; |
544 if (FAT().GetNextClusterL(cluster)) |
543 |
545 {//-- truncate the cluster chain |
544 if (FAT().GetNextClusterL(cluster)) |
546 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
545 {//-- truncate the cluster chain |
547 FAT().FreeClusterListL(cluster); |
546 FAT().WriteFatEntryEofL(iCurrentPos.iCluster); |
548 } |
547 FAT().FreeClusterListL(cluster); |
549 |
548 } |
|
549 |
550 ClearIndex(aNewSize); |
550 ClearIndex(aNewSize); |
551 FAT().FlushL(); |
551 FAT().FlushL(); |
552 } |
552 } |
553 |
553 |
554 //----------------------------------------------------------------------------- |
554 //----------------------------------------------------------------------------- |
555 /** |
555 /** |
556 Expand a file. |
556 Expand a file. |
557 |
557 |
558 @param aNewSize new file size. |
558 @param aNewSize new file size. |
559 @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed |
559 @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed |
560 */ |
560 */ |
561 void CFatFileCB::DoExpandFileL(TUint32 aNewSize, TBool aForceCachesFlush) |
561 void CFatFileCB::DoExpandFileL(TUint32 aNewSize, TBool aForceCachesFlush) |
562 { |
562 { |
563 ASSERT(FCB_FileSize() < aNewSize); |
563 ASSERT(FCB_FileSize() < aNewSize); |
564 ASSERT(FileSizeModified()); |
564 ASSERT(FileSizeModified()); |
565 |
565 |
566 const TUint32 KClusterSzLog2 = ClusterSizeLog2(); |
566 const TUint32 KClusterSzLog2 = ClusterSizeLog2(); |
567 const TUint32 newSizeClusters = (TUint32)(((TUint64)aNewSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2); |
567 const TUint32 newSizeClusters = (TUint32)(((TUint64)aNewSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2); |
568 |
568 |
569 |
569 |
570 //-- expanding a file |
570 //-- expanding a file |
571 if (FCB_StartCluster() == 0) |
571 if (FCB_StartCluster() == 0) |
572 {//-- the initial file size is 0 (no cluster chain) |
572 {//-- the initial file size is 0 (no cluster chain) |
573 |
573 |
574 ClearIndex(0); //-- clear seek index array |
574 ClearIndex(0); //-- clear seek index array |
575 //-- FAT().FreeClusterHint() will give us a hint of the last free cluster |
575 //-- FAT().FreeClusterHint() will give us a hint of the last free cluster |
576 const TUint32 tempStartCluster=FAT().AllocateClusterListL(newSizeClusters, FAT().FreeClusterHint()); |
576 const TUint32 tempStartCluster=FAT().AllocateClusterListL(newSizeClusters, FAT().FreeClusterHint()); |
577 FAT().FlushL(); |
577 FAT().FlushL(); |
578 |
578 |
579 iCurrentPos.iCluster=tempStartCluster; |
579 iCurrentPos.iCluster=tempStartCluster; |
580 FCB_SetStartCluster(tempStartCluster); |
580 FCB_SetStartCluster(tempStartCluster); |
581 FCB_SetFileSize(aNewSize); |
581 FCB_SetFileSize(aNewSize); |
582 FlushAllL(); |
582 FlushAllL(); |
583 } |
583 } |
584 else |
584 else |
585 { |
585 { |
586 const TUint curSize = FCB_FileSize(); |
586 const TUint curSize = FCB_FileSize(); |
587 const TUint32 oldSizeClusters = ((curSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2); |
587 const TUint32 oldSizeClusters = ((curSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2); |
588 ASSERT(newSizeClusters >= oldSizeClusters); |
588 ASSERT(newSizeClusters >= oldSizeClusters); |
589 const TUint newClusters = newSizeClusters-oldSizeClusters; //-- Number of clusters we need to append to the existing cluster chain |
589 const TUint newClusters = newSizeClusters-oldSizeClusters; //-- Number of clusters we need to append to the existing cluster chain |
590 if (newClusters) |
590 if (newClusters) |
591 { |
591 { |
592 TEntryPos currentPos=iCurrentPos; |
592 TEntryPos currentPos=iCurrentPos; |
593 CheckPosL(FCB_FileSize()); |
593 CheckPosL(FCB_FileSize()); |
594 FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster); |
594 FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster); |
595 iCurrentPos=currentPos; |
595 iCurrentPos=currentPos; |
596 } |
596 } |
597 |
597 |
598 FAT().FlushL(); |
598 FAT().FlushL(); |
599 |
599 |
600 if(aForceCachesFlush) // write file size if increasing |
600 if(!IsSequentialMode() && aForceCachesFlush) // Write file size directly to its dir. entry if a cache flush |
601 WriteFileSizeL(aNewSize); |
601 WriteFileSizeL(aNewSize); // is needed and rugged FAT is not ignored by client |
602 } |
602 } |
603 |
603 |
604 } |
604 } |
605 |
605 |
606 //----------------------------------------------------------------------------- |
606 //----------------------------------------------------------------------------- |
607 /** |
607 /** |
608 Set file size. This can involve extending/truncating file's cluster chain. |
608 Set file size. This can involve extending/truncating file's cluster chain. |
609 @param aSize new file size |
609 @param aSize new file size |
610 @param aForceCachesFlush if ETrue, all changes in metadata will go to the media immediately. |
610 @param aForceCachesFlush if ETrue, all changes in metadata will go to the media immediately. |
611 it is used in Rugged FAT mode. |
611 it is used in Rugged FAT mode. |
612 */ |
612 */ |
613 void CFatFileCB::DoSetSizeL(TUint aSize, TBool aForceCachesFlush) |
613 void CFatFileCB::DoSetSizeL(TUint aSize, TBool aForceCachesFlush) |
614 { |
614 { |
615 __PRINT4(_L("CFatFileCB::DoSetSizeL[0x%x] sz:%d, oldSz:%d, flush:%d"), this, aSize, FCB_FileSize(), aForceCachesFlush); |
615 __PRINT4(_L("CFatFileCB::DoSetSizeL[0x%x] sz:%d, oldSz:%d, flush:%d"), this, aSize, FCB_FileSize(), aForceCachesFlush); |
616 |
616 |
617 FatMount().CheckStateConsistentL(); |
617 FatMount().CheckStateConsistentL(); |
618 FatMount().CheckWritableL(); |
618 FatMount().CheckWritableL(); |
619 |
619 |
620 |
620 |
621 // Can not change the file size if it is clamped |
621 // Can not change the file size if it is clamped |
622 if(Mount().IsFileClamped(MAKE_TINT64(0,FCB_StartCluster())) > 0) |
622 if(Mount().IsFileClamped(MAKE_TINT64(0,FCB_StartCluster())) > 0) |
623 User::Leave(KErrInUse); |
623 User::Leave(KErrInUse); |
624 |
624 |
625 if(aSize == FCB_FileSize()) |
625 if(aSize == FCB_FileSize()) |
626 return; |
626 return; |
627 |
627 |
628 IndicateFileSizeModified(ETrue); |
628 IndicateFileSizeModified(ETrue); |
629 IndicateFileAttModified(ETrue); // ensure file size is flushed |
629 IndicateFileAttModified(ETrue); // ensure file size is flushed |
630 |
630 |
765 |
765 |
766 #endif //#ifndef ALWAYS_UPDATE_ENTRY_TS_ON_FLUSH |
766 #endif //#ifndef ALWAYS_UPDATE_ENTRY_TS_ON_FLUSH |
767 |
767 |
768 if(bUpdateDirEntry) |
768 if(bUpdateDirEntry) |
769 {//-- write entry to the media |
769 {//-- write entry to the media |
770 __PRINT(_L(" CFatFileCB::FlushAllL #1")); |
770 __PRINT(_L(" CFatFileCB::FlushAllL #1")); |
771 entry.SetAttributes(Att() & KEntryAttMaskSupported); |
771 entry.SetAttributes(Att() & KEntryAttMaskSupported); |
772 entry.SetSize(FCB_FileSize()); |
772 entry.SetSize(FCB_FileSize()); |
773 entry.SetTime(iModified, timeOffset); |
773 entry.SetTime(iModified, timeOffset); |
774 |
774 |
775 entry.SetStartCluster(FCB_StartCluster()); |
775 entry.SetStartCluster(FCB_StartCluster()); |
776 |
776 |
777 const TBool setNotify = FatMount().GetNotifyUser(); |
777 const TBool setNotify = FatMount().GetNotifyUser(); |
778 if(setNotify) |
778 if(setNotify) |
779 { |
779 { |
780 FatMount().SetNotifyOff(); // do not launch a notifier |
780 FatMount().SetNotifyOff(); // do not launch a notifier |
781 } |
781 } |
782 |
782 |
783 TRAPD(ret, FatMount().WriteDirEntryL(iFileDosEntryPos,entry)); |
783 TRAPD(ret, FatMount().WriteDirEntryL(iFileDosEntryPos,entry)); |
784 |
784 |
785 if(setNotify) |
785 if(setNotify) |
786 { |
786 { |
787 FatMount().SetNotifyOn(); |
787 FatMount().SetNotifyOn(); |
788 } |
788 } |
789 |
789 |
790 User::LeaveIfError(ret); |
790 User::LeaveIfError(ret); |
791 |
791 |
792 IndicateFileSizeModified(EFalse); |
792 IndicateFileSizeModified(EFalse); |
793 IndicateFileTimeModified(EFalse); |
793 IndicateFileTimeModified(EFalse); |
794 } |
794 } |
795 |
795 |
796 |
796 |
797 //-- KEntryAttModified must be reset anyway |
797 //-- KEntryAttModified must be reset anyway |
798 IndicateFileAttModified(EFalse); |
798 IndicateFileAttModified(EFalse); |
799 } |
799 } |
800 |
800 |
801 //----------------------------------------------------------------------------- |
801 //----------------------------------------------------------------------------- |
802 |
802 |
803 /** |
803 /** |
804 Rename already opened file. |
804 Rename already opened file. |
805 @param aNewName new file name; all trailing dots from the name will be removed |
805 @param aNewName new file name; all trailing dots from the name will be removed |
806 */ |
806 */ |
807 void CFatFileCB::RenameL(const TDesC& aNewName) |
807 void CFatFileCB::RenameL(const TDesC& aNewName) |
808 { |
808 { |
809 __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName); |
809 __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName); |
810 |
810 |
811 FatMount().CheckStateConsistentL(); |
811 FatMount().CheckStateConsistentL(); |
812 FatMount().CheckWritableL(); |
812 FatMount().CheckWritableL(); |
813 |
813 |
814 const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name |
814 const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name |
815 |
815 |
816 |
816 |
817 FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename, iFileDosEntryPos); |
817 FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename, iFileDosEntryPos); |
818 |
818 |
819 AllocBufferL(iFileName, fileName); |
819 AllocBufferL(iFileName, fileName); |
820 |
820 |
821 if(!FatMount().IsRuggedFSys()) |
821 if(!FatMount().IsRuggedFSys()) |
822 FAT().FlushL(); |
822 FAT().FlushL(); |
823 } |
823 } |
824 |
824 |
825 |
825 |
826 //*********************************************************** |
826 //*********************************************************** |
827 //* BlockMap interface |
827 //* BlockMap interface |
828 //*********************************************************** |
828 //*********************************************************** |
829 |
829 |
830 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos) |
830 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos) |
831 // |
831 // |
832 // Retrieves the block map of a given section of the file, in the FAT file system. |
832 // Retrieves the block map of a given section of the file, in the FAT file system. |
833 // |
833 // |
834 { |
834 { |
835 __PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos); |
835 __PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos); |
836 |
836 |
837 if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) ) |
837 if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) ) |
838 return KErrNotSupported; |
838 return KErrNotSupported; |
839 |
839 |
840 TUint startPos = I64LOW(aStartPos); |
840 TUint startPos = I64LOW(aStartPos); |
841 TUint endPos = I64LOW(aEndPos); |
841 TUint endPos = I64LOW(aEndPos); |
842 |
842 |
843 // aEndPos will always be >=0 at this point |
843 // aEndPos will always be >=0 at this point |
844 const TUint length = endPos - startPos; |
844 const TUint length = endPos - startPos; |
845 |
845 |
846 // Store the position of cluster zero in aInfo |
846 // Store the position of cluster zero in aInfo |
847 CFatMountCB& fatMount = FatMount(); |
847 CFatMountCB& fatMount = FatMount(); |
848 |
848 |
849 TInt drvNo=-1; |
849 TInt drvNo=-1; |
850 TBusLocalDrive* locDrv; |
850 TBusLocalDrive* locDrv; |
851 if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives)) |
851 if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives)) |
852 aInfo.iLocalDriveNumber=drvNo; |
852 aInfo.iLocalDriveNumber=drvNo; |
853 else |
853 else |
854 return KErrNotSupported; |
854 return KErrNotSupported; |
855 |
855 |
856 TInt r; |
|
857 |
|
858 // Fetch the address of cluster 0 |
856 // Fetch the address of cluster 0 |
859 TRAP(r, aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytesL(KFirstClusterNum)); |
857 aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytes(KFirstClusterNum); |
860 if (r != KErrNone) |
858 |
861 return r; |
859 TRAPD(r, CheckPosL(startPos)); |
862 |
860 if (r != KErrNone) |
863 |
861 return r; |
864 TRAP(r, CheckPosL(startPos)); |
862 |
865 if (r != KErrNone) |
863 aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos); |
866 return r; |
864 aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2(); |
867 |
865 const TUint myStartPos = iCurrentPos.iPos; |
868 aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos); |
866 if ( myStartPos + length > FCB_FileSize()) |
869 aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2(); |
867 return KErrArgument; |
870 const TUint myStartPos = iCurrentPos.iPos; |
868 |
871 if ( myStartPos + length > FCB_FileSize()) |
869 TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo)); |
872 return KErrArgument; |
870 if (r != KErrNone) |
873 |
871 return r; |
874 TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo)); |
872 |
875 if (r != KErrNone) |
873 aStartPos = iCurrentPos.iPos; |
876 return r; |
874 if ((I64LOW(aStartPos) == FCB_FileSize()) || ( I64LOW(aStartPos) == (myStartPos + length))) |
877 |
875 return KErrCompletion; |
878 aStartPos = iCurrentPos.iPos; |
876 else |
879 if ((I64LOW(aStartPos) == FCB_FileSize()) || ( I64LOW(aStartPos) == (myStartPos + length))) |
877 return KErrNone; |
880 return KErrCompletion; |
878 } |
881 else |
|
882 return KErrNone; |
|
883 } |
|
884 |
|
885 |
879 |
886 |
880 |
887 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
881 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
888 { |
882 { |
889 switch(aInterfaceId) |
883 switch(aInterfaceId) |
890 { |
884 { |
891 case EExtendedFileInterface: |
885 case EExtendedFileInterface: |
892 ((CFileCB::MExtendedFileInterface*&) aInterface) = this; |
886 ((CFileCB::MExtendedFileInterface*&) aInterface) = this; |
893 return KErrNone; |
887 return KErrNone; |
894 |
888 |
895 case EBlockMapInterface: |
889 case EBlockMapInterface: |
896 aInterface = (CFileCB::MBlockMapInterface*) this; |
890 aInterface = (CFileCB::MBlockMapInterface*) this; |
897 return KErrNone; |
891 return KErrNone; |
898 |
892 |
899 case EGetLocalDrive: |
893 case EGetLocalDrive: |
900 return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface); |
894 return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface); |
901 |
895 |
902 default: |
896 default: |
903 return CFileCB::GetInterface(aInterfaceId,aInterface,aInput); |
897 return CFileCB::GetInterface(aInterfaceId,aInterface,aInput); |
904 } |
898 } |
905 } |
899 } |
906 |
|
907 |
|
908 |
900 |
909 |
901 |
910 /** |
902 /** |
911 Overwrites file's start cluster (iStartCluster) in its directory entry. |
903 Overwrites file's start cluster (iStartCluster) in its directory entry. |
912 */ |
904 */ |
913 void CFatFileCB::FlushStartClusterL() |
905 void CFatFileCB::FlushStartClusterL() |
914 { |
906 { |
915 __PRINT1(_L("CFatFileCB::FlushStartClusterL[0x%x]"), this); |
907 __PRINT1(_L("CFatFileCB::FlushStartClusterL[0x%x]"), this); |
916 |
908 |
917 CFatMountCB& mount = FatMount(); |
909 CFatMountCB& mount = FatMount(); |
918 TFatDirEntry dirEntry; |
910 TFatDirEntry dirEntry; |
919 |
911 |
920 mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry |
912 mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry |
921 dirEntry.SetStartCluster(FCB_StartCluster()); //-- set new start cluster |
913 dirEntry.SetStartCluster(FCB_StartCluster()); //-- set new start cluster |
922 mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back |
914 mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back |
923 } |
915 } |
924 |
916 |
925 |
917 |
926 /** |
918 /** |
927 This is a RuggedFAT - specific method. Writes file size to the corresponding field of its file directory entry. |
919 This is a RuggedFAT - specific method. Writes file size to the corresponding field of its file directory entry. |
928 */ |
920 */ |
929 void CFatFileCB::WriteFileSizeL(TUint aSize) |
921 void CFatFileCB::WriteFileSizeL(TUint aSize) |
930 { |
922 { |
931 __PRINT2(_L("CFatFileCB::WriteFileSizeL[0x%x], sz:%d"), this, aSize); |
923 __PRINT2(_L("CFatFileCB::WriteFileSizeL[0x%x], sz:%d"), this, aSize); |
932 |
924 |
933 CFatMountCB& mount = FatMount(); |
925 CFatMountCB& mount = FatMount(); |
934 TFatDirEntry dirEntry; |
926 TFatDirEntry dirEntry; |
935 |
927 |
936 mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry |
928 mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry |