27 |
34 |
28 @param aDiskSizeInSectors Size of volume in sectors |
35 @param aDiskSizeInSectors Size of volume in sectors |
29 @return system-wide error code |
36 @return system-wide error code |
30 */ |
37 */ |
31 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps) |
38 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps) |
32 { |
39 { |
33 if( Drive().IsRemovable() ) |
40 if( Drive().IsRemovable() ) |
34 iNumberOfFats = KNumberOfFatsExternal; |
41 iNumberOfFats = KNumberOfFatsExternal; |
35 else |
42 else |
36 iNumberOfFats = KNumberOfFatsInternal; |
43 iNumberOfFats = KNumberOfFatsInternal; |
37 |
44 |
38 iReservedSectors=KDefFatResvdSec; |
45 iReservedSectors=KDefFatResvdSec; |
39 if (aDiskSizeInSectors<4084*1) // < 2MB |
46 if (aDiskSizeInSectors<4084*1) // < 2MB |
40 { |
47 { |
41 iRootDirEntries=128; |
48 iRootDirEntries=128; |
42 iSectorsPerCluster=1; |
49 iSectorsPerCluster=1; |
43 iFileSystemName=KFileSystemName12; |
50 iFileSystemName=KFileSystemName12; |
44 iSectorsPerFat=MaxFat12Sectors(); |
51 iSectorsPerFat=MaxFat12Sectors(); |
45 } |
52 } |
46 else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors) |
53 else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors) |
47 { |
54 { |
48 iRootDirEntries=256; |
55 iRootDirEntries=256; |
49 iSectorsPerCluster=2; |
56 iSectorsPerCluster=2; |
50 iFileSystemName=KFileSystemName12; |
57 iFileSystemName=KFileSystemName12; |
51 iSectorsPerFat=MaxFat12Sectors(); |
58 iSectorsPerFat=MaxFat12Sectors(); |
52 } |
59 } |
53 else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors) |
60 else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors) |
54 { |
61 { |
55 iRootDirEntries=512; |
62 iRootDirEntries=512; |
56 iSectorsPerCluster=4; |
63 iSectorsPerCluster=4; |
57 iFileSystemName=KFileSystemName12; |
64 iFileSystemName=KFileSystemName12; |
58 iSectorsPerFat=MaxFat12Sectors(); |
65 iSectorsPerFat=MaxFat12Sectors(); |
59 } |
66 } |
60 else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors) |
67 else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors) |
61 { |
68 { |
62 iRootDirEntries=512; |
69 iRootDirEntries=512; |
63 iSectorsPerCluster=8; |
70 iSectorsPerCluster=8; |
64 iFileSystemName=KFileSystemName12; |
71 iFileSystemName=KFileSystemName12; |
65 iSectorsPerFat=MaxFat12Sectors(); |
72 iSectorsPerFat=MaxFat12Sectors(); |
66 } |
73 } |
67 else // >= 16Mb - FAT16 |
74 else // >= 16Mb - FAT16 |
68 { |
75 { |
69 iFileSystemName=KFileSystemName16; |
76 iFileSystemName=KFileSystemName16; |
70 TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; |
77 TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; |
71 iRootDirEntries=512; |
78 iRootDirEntries=512; |
72 iSectorsPerCluster=1; |
79 iSectorsPerCluster=1; |
73 while (minSectorsPerCluster>iSectorsPerCluster) |
80 while (minSectorsPerCluster>iSectorsPerCluster) |
74 iSectorsPerCluster<<=1; |
81 iSectorsPerCluster<<=1; |
75 iSectorsPerFat=MaxFat16Sectors(); |
82 iSectorsPerFat=MaxFat16Sectors(); |
76 } |
83 } |
77 |
84 |
78 // Ensure cluster size is a multiple of the block size |
85 // Ensure cluster size is a multiple of the block size |
79 TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; |
86 TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; |
80 __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); |
87 __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); |
81 ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); |
88 ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); |
82 if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) |
89 if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) |
83 { |
90 { |
84 __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); |
91 __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); |
85 AdjustClusterSize(blockSizeInSectors); |
92 AdjustClusterSize(blockSizeInSectors); |
86 __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); |
93 __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); |
87 } |
94 } |
88 |
95 |
89 // Align first data sector on an erase block boundary if |
96 // Align first data sector on an erase block boundary if |
90 // (1) the iEraseBlockSize is specified |
97 // (1) the iEraseBlockSize is specified |
91 // (2) the start of the partition is already aligned to an erase block boundary, |
98 // (2) the start of the partition is already aligned to an erase block boundary, |
92 // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize |
99 // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize |
93 __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); |
100 __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); |
94 TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; |
101 TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; |
95 __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); |
102 __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); |
96 ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); |
103 ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); |
97 ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); |
104 ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); |
98 if ((eraseblockSizeInSectors != 0) && |
105 if ((eraseblockSizeInSectors != 0) && |
99 (iHiddenSectors % eraseblockSizeInSectors == 0) && |
106 (iHiddenSectors % eraseblockSizeInSectors == 0) && |
100 (IsPowerOf2(eraseblockSizeInSectors)) && |
107 (IsPowerOf2(eraseblockSizeInSectors)) && |
101 (eraseblockSizeInSectors >= blockSizeInSectors)) |
108 (eraseblockSizeInSectors >= blockSizeInSectors)) |
102 { |
109 { |
103 TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); |
110 TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); |
104 ASSERT(r == KErrNone); |
111 ASSERT(r == KErrNone); |
105 (void) r; |
112 (void) r; |
106 } |
113 } |
107 __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); |
114 __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); |
108 __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); |
115 __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); |
109 |
116 |
110 return KErrNone; |
117 return KErrNone; |
111 } |
118 } |
112 |
119 |
113 TInt CFatFormatCB::FirstDataSector() const |
120 TInt CFatFormatCB::FirstDataSector() const |
114 { |
121 { |
115 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
122 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
116 return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors; |
123 return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors; |
117 } |
124 } |
118 |
125 |
119 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster) |
126 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster) |
120 { |
127 { |
121 const TInt KMaxSecPerCluster = 64; // 32K |
128 const TInt KMaxSecPerCluster = 64; // 32K |
122 while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2)) |
129 while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2)) |
123 iSectorsPerCluster<<= 1; |
130 iSectorsPerCluster<<= 1; |
124 } |
131 } |
125 |
132 |
126 // AdjustFirstDataSectorAlignment() |
133 // AdjustFirstDataSectorAlignment() |
127 // Attempts to align the first data sector on an erase block boundary by modifying the |
134 // Attempts to align the first data sector on an erase block boundary by modifying the |
128 // number of reserved sectors. |
135 // number of reserved sectors. |
129 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors) |
136 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors) |
130 { |
137 { |
131 const TBool bFat16 = Is16BitFat(); |
138 const TBool bFat16 = Is16BitFat(); |
132 |
139 |
133 // Save these 2 values in the event of a convergence failure; this should |
140 // Save these 2 values in the event of a convergence failure; this should |
134 // hopefully never happen, but we will cater for this in release mode to be safe, |
141 // hopefully never happen, but we will cater for this in release mode to be safe, |
135 TInt reservedSectorsSaved = iReservedSectors; |
142 TInt reservedSectorsSaved = iReservedSectors; |
136 TInt sectorsPerFatSaved = iSectorsPerFat; |
143 TInt sectorsPerFatSaved = iSectorsPerFat; |
137 |
144 |
138 TInt reservedSectorsOld = 0; |
145 TInt reservedSectorsOld = 0; |
139 |
146 |
140 // zero for FAT32 |
147 // zero for FAT32 |
141 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
148 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
142 TInt fatSectors = 0; |
149 TInt fatSectors = 0; |
143 |
150 |
144 TInt KMaxIterations = 10; |
151 TInt KMaxIterations = 10; |
145 TInt n; |
152 TInt n; |
146 for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++) |
153 for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++) |
147 { |
154 { |
148 reservedSectorsOld = iReservedSectors; |
155 reservedSectorsOld = iReservedSectors; |
149 |
156 |
150 iSectorsPerFat = bFat16 ? MaxFat16Sectors() : MaxFat12Sectors(); |
157 iSectorsPerFat = bFat16 ? MaxFat16Sectors() : MaxFat12Sectors(); |
151 |
158 |
152 fatSectors = iSectorsPerFat * iNumberOfFats; |
159 fatSectors = iSectorsPerFat * iNumberOfFats; |
153 |
160 |
154 // calculate number of blocks |
161 // calculate number of blocks |
155 TInt nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors; |
162 TInt nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors; |
156 |
163 |
157 iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors; |
164 iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors; |
158 } |
165 } |
159 |
166 |
160 ASSERT(iReservedSectors >= (TInt) KDefFatResvdSec); |
167 ASSERT(iReservedSectors >= (TInt) KDefFatResvdSec); |
161 |
168 |
162 if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0) |
169 if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0) |
163 { |
170 { |
164 return KErrNone; |
171 return KErrNone; |
165 } |
172 } |
166 else |
173 else |
167 { |
174 { |
168 iReservedSectors = reservedSectorsSaved; |
175 iReservedSectors = reservedSectorsSaved; |
169 iSectorsPerFat = sectorsPerFatSaved; |
176 iSectorsPerFat = sectorsPerFatSaved; |
170 return KErrGeneral; |
177 return KErrGeneral; |
171 } |
178 } |
172 } |
179 } |
173 |
180 |
174 /** |
181 /** |
175 Initialize the user specific format parameters for fixed sized disk. |
182 Initialize the user specific format parameters for fixed sized disk. |
176 |
183 |
177 @param aDiskSizeInSectors disk size in sectors |
184 @param aDiskSizeInSectors disk size in sectors |
178 @return system-wide error code |
185 @return system-wide error code |
179 */ |
186 */ |
180 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors) |
187 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors) |
181 { |
188 { |
182 //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32 |
189 //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32 |
183 |
190 |
184 if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable) |
191 if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable) |
185 iNumberOfFats = 1; |
192 iNumberOfFats = 1; |
186 else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables) |
193 else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables) |
187 iNumberOfFats = 2; |
194 iNumberOfFats = 2; |
188 else if(Drive().IsRemovable()) |
195 else if(Drive().IsRemovable()) |
189 iNumberOfFats = KNumberOfFatsExternal; |
196 iNumberOfFats = KNumberOfFatsExternal; |
190 else |
197 else |
191 iNumberOfFats = KNumberOfFatsInternal; |
198 iNumberOfFats = KNumberOfFatsInternal; |
192 |
199 |
193 |
200 |
194 if(iSpecialInfo().iReservedSectors == 0) |
201 if(iSpecialInfo().iReservedSectors == 0) |
195 iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16) |
202 iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16) |
196 else |
203 else |
197 iReservedSectors = iSpecialInfo().iReservedSectors; |
204 iReservedSectors = iSpecialInfo().iReservedSectors; |
198 |
205 |
199 |
206 |
200 const TInt KMaxSecPerCluster = 64; |
207 const TInt KMaxSecPerCluster = 64; |
201 const TInt KDefaultSecPerCluster= 8; //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified |
208 const TInt KDefaultSecPerCluster= 8; //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified |
202 |
209 |
203 iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster; |
210 iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster; |
204 if(iSectorsPerCluster <= 0) |
211 if(iSectorsPerCluster <= 0) |
205 {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster |
212 {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster |
206 iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later |
213 iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later |
207 } |
214 } |
208 else |
215 else |
209 { |
216 { |
210 iSectorsPerCluster = Min(1<<Log2(iSectorsPerCluster), KMaxSecPerCluster); |
217 iSectorsPerCluster = Min(1<<Log2(iSectorsPerCluster), KMaxSecPerCluster); |
211 } |
218 } |
212 |
219 |
213 //----------------------------------------- |
220 //----------------------------------------- |
214 |
221 |
215 if (aDiskSizeInSectors < 4096) // < 2MB |
222 if (aDiskSizeInSectors < 4096) // < 2MB |
216 { |
223 { |
217 iSectorsPerCluster = 1; |
224 iSectorsPerCluster = 1; |
218 iRootDirEntries = 128; |
225 iRootDirEntries = 128; |
219 } |
226 } |
220 else if (aDiskSizeInSectors < 8192) // < 4MB |
227 else if (aDiskSizeInSectors < 8192) // < 4MB |
221 { |
228 { |
222 iSectorsPerCluster = Min(iSectorsPerCluster, 2); |
229 iSectorsPerCluster = Min(iSectorsPerCluster, 2); |
223 iRootDirEntries = 256; |
230 iRootDirEntries = 256; |
224 } |
231 } |
225 else if (aDiskSizeInSectors < 32768) // < 16MB |
232 else if (aDiskSizeInSectors < 32768) // < 16MB |
226 { |
233 { |
227 iSectorsPerCluster = Min(iSectorsPerCluster, 4); |
234 iSectorsPerCluster = Min(iSectorsPerCluster, 4); |
228 iRootDirEntries = 512; |
235 iRootDirEntries = 512; |
229 } |
236 } |
230 else if (aDiskSizeInSectors < 131072) // < 64MB |
237 else if (aDiskSizeInSectors < 131072) // < 64MB |
231 { |
238 { |
232 iSectorsPerCluster = Min(iSectorsPerCluster, 8); |
239 iSectorsPerCluster = Min(iSectorsPerCluster, 8); |
233 iRootDirEntries = 512; |
240 iRootDirEntries = 512; |
234 } |
241 } |
235 else // >= 64Mb |
242 else // >= 64Mb |
236 iRootDirEntries = 512; |
243 iRootDirEntries = 512; |
237 |
244 |
238 //----------------------------------------- |
245 //----------------------------------------- |
239 |
246 |
240 TLDFormatInfo::TFATBits fatBits = iSpecialInfo().iFATBits; |
247 TLDFormatInfo::TFATBits fatBits = iSpecialInfo().iFATBits; |
241 if (fatBits == TLDFormatInfo::EFBDontCare) |
248 if (fatBits == TLDFormatInfo::EFBDontCare) |
242 { |
249 { |
243 const TFatType fatType = SuggestFatType(); |
250 const TFatType fatType = SuggestFatType(); |
244 switch(fatType) |
251 switch(fatType) |
245 { |
252 { |
246 case EFat12: |
253 case EFat12: |
247 fatBits = TLDFormatInfo::EFB12; |
254 fatBits = TLDFormatInfo::EFB12; |
248 break; |
255 break; |
249 case EFat16: |
256 case EFat16: |
250 fatBits = TLDFormatInfo::EFB16; |
257 fatBits = TLDFormatInfo::EFB16; |
251 break; |
258 break; |
252 case EFat32: |
259 case EFat32: |
253 fatBits = TLDFormatInfo::EFB32; |
260 fatBits = TLDFormatInfo::EFB32; |
254 break; |
261 break; |
255 case EInvalid: |
262 case EInvalid: |
256 ASSERT(0); |
263 ASSERT(0); |
257 } |
264 } |
258 } |
265 } |
259 |
266 |
260 TFatType reqFatType(EInvalid); //-- requested FAT type |
267 TFatType reqFatType(EInvalid); //-- requested FAT type |
261 |
268 |
262 switch (fatBits) |
269 switch (fatBits) |
263 { |
270 { |
290 return KErrArgument; |
297 return KErrArgument; |
291 } |
298 } |
292 |
299 |
293 |
300 |
294 return KErrNone; |
301 return KErrNone; |
295 } |
302 } |
296 |
303 |
297 /** |
304 /** |
298 Initialize the format parameters for a custom fixed sized disk |
305 Initialize the format parameters for a custom fixed sized disk |
299 |
306 |
300 @param aFormatInfo The custom format parameters |
307 @param aFormatInfo The custom format parameters |
301 @return system-wide error code |
308 @return system-wide error code |
302 */ |
309 */ |
303 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo) |
310 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo) |
304 { |
311 { |
305 if(aFormatInfo.iFlags & TLDFormatInfo::EOneFatTable) |
312 if(aFormatInfo.iFlags & TLDFormatInfo::EOneFatTable) |
306 iNumberOfFats = 1; |
313 iNumberOfFats = 1; |
307 else if(aFormatInfo.iFlags & TLDFormatInfo::ETwoFatTables) |
314 else if(aFormatInfo.iFlags & TLDFormatInfo::ETwoFatTables) |
308 iNumberOfFats = 2; |
315 iNumberOfFats = 2; |
309 else if(Drive().IsRemovable()) |
316 else if(Drive().IsRemovable()) |
310 iNumberOfFats = KNumberOfFatsExternal; |
317 iNumberOfFats = KNumberOfFatsExternal; |
311 else |
318 else |
312 iNumberOfFats = KNumberOfFatsInternal; |
319 iNumberOfFats = KNumberOfFatsInternal; |
313 |
320 |
314 iRootDirEntries=512; |
321 iRootDirEntries=512; |
315 |
322 |
316 iSectorsPerCluster = aFormatInfo.iSectorsPerCluster; |
323 iSectorsPerCluster = aFormatInfo.iSectorsPerCluster; |
317 iSectorsPerTrack = aFormatInfo.iSectorsPerTrack; |
324 iSectorsPerTrack = aFormatInfo.iSectorsPerTrack; |
318 iNumberOfHeads = aFormatInfo.iNumberOfSides; |
325 iNumberOfHeads = aFormatInfo.iNumberOfSides; |
319 iReservedSectors = aFormatInfo.iReservedSectors ? aFormatInfo.iReservedSectors : KDefFatResvdSec; |
326 iReservedSectors = aFormatInfo.iReservedSectors ? aFormatInfo.iReservedSectors : KDefFatResvdSec; |
320 |
327 |
321 switch (aFormatInfo.iFATBits) |
328 switch (aFormatInfo.iFATBits) |
322 { |
329 { |
323 case TLDFormatInfo::EFB12: |
330 case TLDFormatInfo::EFB12: |
324 iFileSystemName = KFileSystemName12; |
331 iFileSystemName = KFileSystemName12; |
325 iSectorsPerFat = MaxFat12Sectors(); |
332 iSectorsPerFat = MaxFat12Sectors(); |
326 break; |
|
327 |
|
328 case TLDFormatInfo::EFB16: |
|
329 iFileSystemName = KFileSystemName16; |
|
330 iSectorsPerFat = MaxFat16Sectors(); |
|
331 break; |
333 break; |
332 |
334 |
333 default: |
335 case TLDFormatInfo::EFB16: |
334 { |
336 iFileSystemName = KFileSystemName16; |
335 TInt64 clusters64 = (aFormatInfo.iCapacity / KDefaultSectorSize) / iSectorsPerCluster; |
337 iSectorsPerFat = MaxFat16Sectors(); |
336 TInt clusters = I64LOW(clusters64); |
338 break; |
337 if (clusters < 4085) |
339 |
338 { |
340 default: |
339 iFileSystemName = KFileSystemName12; |
341 { |
340 iSectorsPerFat = MaxFat12Sectors(); |
342 TInt64 clusters64 = (aFormatInfo.iCapacity / KDefaultSectorSize) / iSectorsPerCluster; |
341 } |
343 TInt clusters = I64LOW(clusters64); |
342 else |
344 if (clusters < 4085) |
343 { |
345 { |
344 iFileSystemName = KFileSystemName16; |
346 iFileSystemName = KFileSystemName12; |
345 iSectorsPerFat = MaxFat16Sectors(); |
347 iSectorsPerFat = MaxFat12Sectors(); |
346 } |
348 } |
347 } |
349 else |
348 } |
350 { |
|
351 iFileSystemName = KFileSystemName16; |
|
352 iSectorsPerFat = MaxFat16Sectors(); |
|
353 } |
|
354 } |
|
355 } |
349 |
356 |
350 return KErrNone; |
357 return KErrNone; |
351 } |
358 } |
352 |
359 |
353 void CFatFormatCB::RecordOldInfoL() |
360 void CFatFormatCB::RecordOldInfoL() |
354 { |
361 { |
355 __PRINT(_L("CFatFormatCB::RecordOldInfoL")); |
362 __PRINT(_L("CFatFormatCB::RecordOldInfoL")); |
356 // Check if mount or disk is corrupt |
363 // Check if mount or disk is corrupt |
357 // This should be stored in member variable because FatMount is remounted |
364 // This should be stored in member variable because FatMount is remounted |
358 // every time RFormat::Next() gets called thus FatMount().Initialised() |
365 // every time RFormat::Next() gets called thus FatMount().Initialised() |
359 // will be inconsistent with previous state. |
366 // will be inconsistent with previous state. |
360 TLocalDriveCapsV3Buf caps; |
367 TLocalDriveCapsV3Buf caps; |
361 User::LeaveIfError(LocalDrive()->Caps(caps)); |
368 User::LeaveIfError(LocalDrive()->Caps(caps)); |
362 iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse; |
369 iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse; |
363 iDiskCorrupt = !FatMount().ConsistentState(); |
370 iDiskCorrupt = !FatMount().ConsistentState(); |
364 iBadClusters.Reset(); |
371 iBadClusters.Reset(); |
365 iBadSectors.Reset(); |
372 iBadSectors.Reset(); |
366 if (!iVariableSize && !iDiskCorrupt && (iMode & EQuickFormat)) |
373 if (!iVariableSize && !iDiskCorrupt && (iMode & EQuickFormat)) |
367 { |
374 { |
368 iOldFirstFreeSector = FatMount().iFirstFreeByte >> FatMount().SectorSizeLog2(); |
375 iOldFirstFreeSector = FatMount().iFirstFreeByte >> FatMount().SectorSizeLog2(); |
369 iOldSectorsPerCluster = FatMount().SectorsPerCluster(); |
376 iOldSectorsPerCluster = FatMount().SectorsPerCluster(); |
370 |
377 |
371 FatMount().FAT().InvalidateCacheL(); //-- invalidate whole FAT cache |
378 FatMount().FAT().InvalidateCacheL(); //-- invalidate whole FAT cache |
372 |
379 |
373 const TInt maxClusterNum = FatMount().iUsableClusters + KFatFirstSearchCluster; |
380 const TInt maxClusterNum = FatMount().iUsableClusters + KFatFirstSearchCluster; |
374 |
381 |
375 // Collect bad cluster information from current FAT table |
382 // Collect bad cluster information from current FAT table |
376 const TUint32 mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit; |
383 const TUint32 mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit; |
377 for (TInt i=KFatFirstSearchCluster; i<maxClusterNum; i++) |
384 for (TInt i=KFatFirstSearchCluster; i<maxClusterNum; i++) |
378 if (FatMount().FAT().ReadL(i) == mark) |
385 if (FatMount().FAT().ReadL(i) == mark) |
384 Create the boot sector on media for the volume. |
391 Create the boot sector on media for the volume. |
385 |
392 |
386 @leave System wide error codes |
393 @leave System wide error codes |
387 */ |
394 */ |
388 void CFatFormatCB::CreateBootSectorL() |
395 void CFatFormatCB::CreateBootSectorL() |
389 { |
396 { |
390 __PRINT1(_L("CFatFormatCB::CreateBootSector() drive:%d"),DriveNumber()); |
397 __PRINT1(_L("CFatFormatCB::CreateBootSector() drive:%d"),DriveNumber()); |
391 |
398 |
392 TFatBootSector bootSector; |
399 TFatBootSector bootSector; |
393 |
400 |
394 bootSector.SetVendorID(KDefaultVendorID); |
401 bootSector.SetVendorID(KDefaultVendorID); |
395 bootSector.SetBytesPerSector(iBytesPerSector); |
402 bootSector.SetBytesPerSector(iBytesPerSector); |
396 bootSector.SetSectorsPerCluster(iSectorsPerCluster); |
403 bootSector.SetSectorsPerCluster(iSectorsPerCluster); |
397 bootSector.SetReservedSectors(iReservedSectors); |
404 bootSector.SetReservedSectors(iReservedSectors); |
398 bootSector.SetNumberOfFats(iNumberOfFats); |
405 bootSector.SetNumberOfFats(iNumberOfFats); |
399 bootSector.SetRootDirEntries(iRootDirEntries); |
406 bootSector.SetRootDirEntries(iRootDirEntries); |
400 if (iMaxDiskSectors<(TInt)KMaxTUint16) |
407 if (iMaxDiskSectors<(TInt)KMaxTUint16) |
401 bootSector.SetTotalSectors(iMaxDiskSectors); |
408 bootSector.SetTotalSectors(iMaxDiskSectors); |
402 else |
409 else |
403 { |
410 { |
404 bootSector.SetTotalSectors(0); |
411 bootSector.SetTotalSectors(0); |
405 bootSector.SetHugeSectors(iMaxDiskSectors); |
412 bootSector.SetHugeSectors(iMaxDiskSectors); |
406 } |
413 } |
407 TInt numberOfClusters=iMaxDiskSectors/iSectorsPerCluster; |
414 TInt numberOfClusters=iMaxDiskSectors/iSectorsPerCluster; |
408 if (numberOfClusters>(TInt)KMaxTUint16) |
415 if (numberOfClusters>(TInt)KMaxTUint16) |
409 User::Leave(KErrTooBig); |
416 User::Leave(KErrTooBig); |
410 bootSector.SetFatSectors(iSectorsPerFat); |
417 bootSector.SetFatSectors(iSectorsPerFat); |
411 bootSector.SetReservedByte(0); |
418 bootSector.SetReservedByte(0); |
412 TTime timeID; |
419 TTime timeID; |
413 timeID.HomeTime(); // System time in future? |
420 timeID.HomeTime(); // System time in future? |
414 bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate UniqueID from time |
421 bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate UniqueID from time |
415 bootSector.SetVolumeLabel(_L8("")); |
422 bootSector.SetVolumeLabel(_L8("")); |
416 bootSector.SetFileSysType(iFileSystemName); |
423 bootSector.SetFileSysType(iFileSystemName); |
417 // Floppy specific info: |
424 // Floppy specific info: |
418 bootSector.SetJumpInstruction(); |
425 bootSector.SetJumpInstruction(); |
419 bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor); |
426 bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor); |
420 bootSector.SetNumberOfHeads(iNumberOfHeads); |
427 bootSector.SetNumberOfHeads(iNumberOfHeads); |
421 bootSector.SetHiddenSectors(iHiddenSectors); |
428 bootSector.SetHiddenSectors(iHiddenSectors); |
422 bootSector.SetSectorsPerTrack(iSectorsPerTrack); |
429 bootSector.SetSectorsPerTrack(iSectorsPerTrack); |
423 bootSector.SetPhysicalDriveNumber(128); |
430 bootSector.SetPhysicalDriveNumber(128); |
424 bootSector.SetExtendedBootSignature(0x29); |
431 bootSector.SetExtendedBootSignature(0x29); |
425 |
432 |
426 |
433 |
427 User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector)); |
434 User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector)); |
428 } |
435 } |
429 |
436 |
430 //------------------------------------------------------------------------------------------------------------------- |
437 //------------------------------------------------------------------------------------------------------------------- |
431 |
438 |
432 /** |
439 /** |
433 Format a disk section, called iteratively to erase whole of media, on last iteration |
440 Format a disk section, called iteratively to erase whole of media, on last iteration |
435 rest of the volume intact. |
442 rest of the volume intact. |
436 |
443 |
437 @leave System wide error code |
444 @leave System wide error code |
438 */ |
445 */ |
439 void CFatFormatCB::DoFormatStepL() |
446 void CFatFormatCB::DoFormatStepL() |
440 { |
447 { |
441 if (iFormatInfo.iFormatIsCurrent==EFalse) |
448 if (iFormatInfo.iFormatIsCurrent==EFalse) |
442 { |
449 { |
443 if (iMode & EForceErase) |
450 if (iMode & EForceErase) |
444 { |
451 { |
445 TInt r = FatMount().ErasePassword(); |
452 TInt r = FatMount().ErasePassword(); |
446 User::LeaveIfError(r); |
453 User::LeaveIfError(r); |
447 // CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(), |
454 // CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(), |
448 // so need to stop a remount from occurring in next call to : |
455 // so need to stop a remount from occurring in next call to : |
449 // TFsFormatNext::DoRequestL((), TDrive::CheckMount(). |
456 // TFsFormatNext::DoRequestL((), TDrive::CheckMount(). |
450 FatMount().Drive().SetChanged(EFalse); |
457 FatMount().Drive().SetChanged(EFalse); |
451 } |
458 } |
452 |
459 |
453 RecordOldInfoL(); |
460 RecordOldInfoL(); |
454 InitializeFormatDataL(); |
461 InitializeFormatDataL(); |
455 FatMount().DoDismount(); |
462 FatMount().DoDismount(); |
456 if (iVariableSize) |
463 if (iVariableSize) |
457 FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize)); |
464 FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize)); |
458 } |
465 } |
459 // |
466 // |
460 // Blank disk if not EQuickFormat |
467 // Blank disk if not EQuickFormat |
461 // |
468 // |
462 if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep) |
469 if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep) |
463 { |
470 { |
464 if (iFormatInfo.iFormatIsCurrent == EFalse) |
471 if (iFormatInfo.iFormatIsCurrent == EFalse) |
465 {//-- firstly invalidate sectors 0-6 inclusive |
472 {//-- firstly invalidate sectors 0-6 inclusive |
466 DoZeroFillMediaL(0, 7*iBytesPerSector); |
473 DoZeroFillMediaL(0, 7*iBytesPerSector); |
467 } |
474 } |
468 |
475 |
469 TInt ret=FatMount().LocalDrive()->Format(iFormatInfo); |
476 TInt ret=FatMount().LocalDrive()->Format(iFormatInfo); |
470 if (ret!=KErrNone && ret!=KErrEof) // Handle format error |
477 if (ret!=KErrNone && ret!=KErrEof) // Handle format error |
471 ret = HandleCorrupt(ret); |
478 ret = HandleCorrupt(ret); |
472 if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format() |
479 if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format() |
473 User::Leave(ret); |
480 User::Leave(ret); |
474 if (ret==KErrNone) |
481 if (ret==KErrNone) |
475 { |
482 { |
476 iCurrentStep=100-(100*iFormatInfo.i512ByteSectorsFormatted)/iMaxDiskSectors; |
483 iCurrentStep=100-(100*iFormatInfo.i512ByteSectorsFormatted)/iMaxDiskSectors; |
477 if (iCurrentStep<=0) |
484 if (iCurrentStep<=0) |
478 iCurrentStep=1; |
485 iCurrentStep=1; |
479 return; |
486 return; |
480 } |
487 } |
481 } |
488 } |
482 |
489 |
483 // ReMount since MBR may have been rewritten and partition may have moved / changed size |
490 // ReMount since MBR may have been rewritten and partition may have moved / changed size |
484 TInt ret = LocalDrive()->ForceRemount(0); |
491 TInt ret = LocalDrive()->ForceRemount(0); |
485 if (ret != KErrNone && ret != KErrNotSupported) |
492 if (ret != KErrNone && ret != KErrNotSupported) |
486 User::Leave(ret); |
493 User::Leave(ret); |
487 |
494 |
488 // MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written |
495 // MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written |
489 InitializeFormatDataL(); |
496 InitializeFormatDataL(); |
490 |
497 |
491 // Translate bad sector number to cluster number which contains that sector |
498 // Translate bad sector number to cluster number which contains that sector |
492 // This only happens in full format, in quick format they are already cluster numbers |
499 // This only happens in full format, in quick format they are already cluster numbers |
493 if (!iVariableSize && !(iMode & EQuickFormat)) |
500 if (!iVariableSize && !(iMode & EQuickFormat)) |
494 User::LeaveIfError(BadSectorToCluster()); |
501 User::LeaveIfError(BadSectorToCluster()); |
495 |
502 |
496 // |
503 // |
497 // Do the rest of the disk in one lump |
504 // Do the rest of the disk in one lump |
498 // |
505 // |
499 iCurrentStep=0; |
506 iCurrentStep=0; |
500 |
507 |
501 |
508 |
502 //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs |
509 //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs |
503 const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position |
510 const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position |
504 |
511 |
505 if (iVariableSize) |
512 if (iVariableSize) |
506 FatMount().EnlargeL(posFatEnd); |
513 FatMount().EnlargeL(posFatEnd); |
507 |
514 |
508 DoZeroFillMediaL(0, posFatEnd); |
515 DoZeroFillMediaL(0, posFatEnd); |
509 |
516 |
510 //-- Zero fill root directory |
517 //-- Zero fill root directory |
511 const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); |
518 const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); |