24 // |
24 // |
25 // Returns the total available ram from UserHal:: or sets an |
25 // Returns the total available ram from UserHal:: or sets an |
26 // arbitrary limit upon the WINS ramdisk. |
26 // arbitrary limit upon the WINS ramdisk. |
27 // |
27 // |
28 static TInt64 GetRamDiskSizeInBytes() |
28 static TInt64 GetRamDiskSizeInBytes() |
29 { |
29 { |
30 |
30 |
31 #if defined(__EPOC32__) |
31 #if defined(__EPOC32__) |
32 TMemoryInfoV1Buf memInfo; |
32 TMemoryInfoV1Buf memInfo; |
33 UserHal::MemoryInfo(memInfo); |
33 UserHal::MemoryInfo(memInfo); |
34 TUint max = memInfo().iTotalRamInBytes; // not really the correct max |
34 TUint max = memInfo().iTotalRamInBytes; // not really the correct max |
35 return max; |
35 return max; |
36 #else |
36 #else |
37 const TInt KArbitraryWinsRamDiskSize=0x400000; //-- Default size for a Ram drive, 4MB |
37 const TInt KArbitraryWinsRamDiskSize=0x400000; //-- Default size for a Ram drive, 4MB |
38 return(KArbitraryWinsRamDiskSize); |
38 return(KArbitraryWinsRamDiskSize); |
39 #endif |
39 #endif |
40 } |
40 } |
41 |
41 |
42 CFatFormatCB::CFatFormatCB() |
42 CFatFormatCB::CFatFormatCB() |
43 { |
43 { |
44 __PRINT1(_L("CFatFormatCB::CFatFormatCB() [%x]"),this); |
44 __PRINT1(_L("CFatFormatCB::CFatFormatCB() [%x]"),this); |
45 } |
45 } |
46 |
46 |
47 CFatFormatCB::~CFatFormatCB() |
47 CFatFormatCB::~CFatFormatCB() |
48 { |
48 { |
49 __PRINT1(_L("CFatFormatCB::~CFatFormatCB() [%x]"),this); |
49 __PRINT1(_L("CFatFormatCB::~CFatFormatCB() [%x]"),this); |
50 iBadSectors.Close(); |
50 iBadSectors.Close(); |
51 iBadClusters.Close(); |
51 iBadClusters.Close(); |
52 } |
52 } |
53 |
53 |
54 /** |
54 /** |
55 Calculate the size of a 16 bit FAT |
55 Calculate the size of a 16 bit FAT |
56 */ |
56 */ |
57 TUint CFatFormatCB::MaxFat16Sectors() const |
57 TUint CFatFormatCB::MaxFat16Sectors() const |
58 { |
58 { |
59 const TUint32 fatSizeInBytes=(2*iMaxDiskSectors)/iSectorsPerCluster+(iBytesPerSector-1); |
59 const TUint32 fatSizeInBytes=(2*iMaxDiskSectors)/iSectorsPerCluster+(iBytesPerSector-1); |
60 return(fatSizeInBytes/iBytesPerSector); |
60 return(fatSizeInBytes/iBytesPerSector); |
61 } |
61 } |
62 |
62 |
63 |
63 |
64 /** |
64 /** |
65 Calculate the size of a 12 bit FAT |
65 Calculate the size of a 12 bit FAT |
66 */ |
66 */ |
67 TUint CFatFormatCB::MaxFat12Sectors() const |
67 TUint CFatFormatCB::MaxFat12Sectors() const |
68 { |
68 { |
69 const TUint32 maxDiskClusters=iMaxDiskSectors/iSectorsPerCluster; |
69 const TUint32 maxDiskClusters=iMaxDiskSectors/iSectorsPerCluster; |
70 const TUint32 fatSizeInBytes=maxDiskClusters+(maxDiskClusters>>1)+(iBytesPerSector-1); |
70 const TUint32 fatSizeInBytes=maxDiskClusters+(maxDiskClusters>>1)+(iBytesPerSector-1); |
71 |
71 |
72 return(fatSizeInBytes/iBytesPerSector); |
72 return(fatSizeInBytes/iBytesPerSector); |
73 } |
73 } |
74 |
74 |
75 //------------------------------------------------------------------------------------------------------------------- |
75 //------------------------------------------------------------------------------------------------------------------- |
76 /** |
76 /** |
77 Fill a media range from aStartPos to aEndPos with zeroes. |
77 Fill a media range from aStartPos to aEndPos with zeroes. |
78 @param aStartPos start media position |
78 @param aStartPos start media position |
110 CleanupStack::PopAndDestroy(&buf); |
110 CleanupStack::PopAndDestroy(&buf); |
111 } |
111 } |
112 |
112 |
113 //------------------------------------------------------------------------------------------------------------------- |
113 //------------------------------------------------------------------------------------------------------------------- |
114 |
114 |
115 static TInt DiskSizeInSectorsL(TInt64 aSizeInBytes) |
115 static TUint32 DiskSizeInSectorsL(TInt64 aSizeInBytes) |
116 { |
116 { |
117 const TInt64 totalSectors64=aSizeInBytes>>KDefSectorSzLog2; |
117 const TInt64 totalSectors64=aSizeInBytes>>KDefSectorSzLog2; |
118 const TInt totalSectors32=I64LOW(totalSectors64); |
118 const TUint32 totalSectors32=I64LOW(totalSectors64); |
119 __PRINT2(_L("Disk size:%LU, max disk sectors:%d"),aSizeInBytes, totalSectors32); |
119 ASSERT(!I64HIGH(totalSectors64)); |
|
120 //__PRINT2(_L("Disk size:%LU, max disk sectors:%d"),aSizeInBytes, totalSectors32); |
120 return totalSectors32; |
121 return totalSectors32; |
121 } |
122 } |
122 |
123 |
123 |
124 //------------------------------------------------------------------------------------------------------------------- |
124 /** |
125 /** |
125 suggest FAT type according to the FAT volume metrics |
126 suggest FAT type according to the FAT volume metrics |
126 @return calculated FAT type |
127 @return calculated FAT type |
127 */ |
128 */ |
128 TFatType CFatFormatCB::SuggestFatType() const |
129 TFatType CFatFormatCB::SuggestFatType() const |
138 return EFat16; |
139 return EFat16; |
139 else |
140 else |
140 return EFat32; |
141 return EFat32; |
141 } |
142 } |
142 |
143 |
|
144 //------------------------------------------------------------------------------------------------------------------- |
143 /** |
145 /** |
144 Initialize format data. |
146 Initialize format data. |
145 */ |
147 */ |
146 void CFatFormatCB::InitializeFormatDataL() |
148 void CFatFormatCB::InitializeFormatDataL() |
147 { |
149 { |
148 |
150 |
149 __PRINT1(_L("CFatFormatCB::InitializeFormatDataL() drv:%d"), Drive().DriveNumber()); |
151 __PRINT1(_L("CFatFormatCB::InitializeFormatDataL() drv:%d"), Drive().DriveNumber()); |
150 TLocalDriveCapsV6Buf caps; |
152 |
151 User::LeaveIfError(LocalDrive()->Caps(caps)); |
153 TLocalDriveCapsV6Buf capsBuf; |
152 iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse; |
154 const TLocalDriveCapsV6& caps = capsBuf(); |
153 |
155 User::LeaveIfError(LocalDrive()->Caps(capsBuf)); |
154 iBytesPerSector=KDefaultSectorSize; |
156 |
155 iSectorSizeLog2 = Log2(iBytesPerSector); |
157 iVariableSize = (caps.iMediaAtt & KMediaAttVariableSize); |
156 iHiddenSectors=caps().iHiddenSectors; |
158 iBytesPerSector=KDefaultSectorSize; |
157 iNumberOfHeads=2; |
159 iSectorSizeLog2 = Log2(iBytesPerSector); |
158 iSectorsPerTrack=16; |
160 iHiddenSectors = caps.iHiddenSectors; |
159 |
161 iNumberOfHeads=2; |
|
162 iSectorsPerTrack=16; |
|
163 |
|
164 TInt nRes=KErrUnknown; |
|
165 |
160 if (iVariableSize) |
166 if (iVariableSize) |
161 {// Variable size implies ram disk |
167 {// Variable size implies ram disk |
162 iMaxDiskSectors=DiskSizeInSectorsL(GetRamDiskSizeInBytes()); |
168 iMaxDiskSectors=DiskSizeInSectorsL(GetRamDiskSizeInBytes()); |
163 InitFormatDataForVariableSizeDisk(iMaxDiskSectors); |
169 nRes = ProcessVolParam_RamDisk(); |
164 } |
170 } |
165 else |
171 else |
166 {//-- fixed-size media |
172 {//-- fixed-size media |
167 iMaxDiskSectors=DiskSizeInSectorsL(caps().iSize); |
173 iMaxDiskSectors=DiskSizeInSectorsL(caps.iSize); |
168 |
174 __PRINT3(_L("::InitializeFormatDataL() iMode:0x%x, ilen:%d, extrai:%d"), iMode, iSpecialInfo.Length(), caps.iExtraInfo); |
169 __PRINT3(_L("::InitializeFormatDataL() iMode:0x%x, ilen:%d, extrai:%d"), iMode, iSpecialInfo.Length(), caps().iExtraInfo); |
175 |
170 |
176 //----------------------------------------------------------------------------------------- |
171 if(iMode & ESpecialFormat) |
177 //-- find out if there are volume parameters specified by the user or media driver. |
172 { |
178 |
173 if(iSpecialInfo.Length()) |
179 //-- meaning: the user has specified its own settings for the volume parameters |
174 { |
180 const TBool bUserFormat = (iMode & ESpecialFormat) && iSpecialInfo.Length(); |
175 if (caps().iExtraInfo) // conflict between user and media |
181 |
176 User::Leave(KErrNotSupported); |
182 //-- meaning: the media driver has its own settings regarding the volume parameters |
177 else // User-specified |
183 const TBool bCustomFormat = caps.iExtraInfo; |
178 User::LeaveIfError(InitFormatDataForFixedSizeDiskUser(iMaxDiskSectors)); |
184 |
179 } |
185 if(bUserFormat && bCustomFormat) |
180 else |
186 { |
181 { |
187 nRes = KErrNotSupported; //-- conflict between user settings and media driver's |
182 if (caps().iExtraInfo) |
188 } |
183 User::LeaveIfError(InitFormatDataForFixedSizeDiskCustom(caps().iFormatInfo)); |
189 else |
|
190 { |
|
191 if(bUserFormat) |
|
192 nRes = ProcessVolParam_User(caps); |
|
193 else if(bCustomFormat) |
|
194 nRes = ProcessVolParam_Custom(caps); |
184 else |
195 else |
185 User::LeaveIfError(InitFormatDataForFixedSizeDiskNormal(iMaxDiskSectors, caps())); |
196 nRes = ProcessVolParam_Default(caps); |
186 } |
197 } |
187 } |
|
188 else //if(iMode & ESpecialFormat) |
|
189 { |
|
190 // Normal format with default values |
|
191 // - Media with special format requirements will always use them |
|
192 // even without the ESpecialFormat option. |
|
193 if(caps().iExtraInfo) |
|
194 User::LeaveIfError(InitFormatDataForFixedSizeDiskCustom(caps().iFormatInfo)); |
|
195 else |
|
196 User::LeaveIfError(InitFormatDataForFixedSizeDiskNormal(iMaxDiskSectors, caps())); |
|
197 } |
|
198 |
|
199 } //else(iVariableSize) |
198 } //else(iVariableSize) |
200 } |
199 |
201 |
200 if(nRes != KErrNone) |
202 /** |
201 { |
203 Initialize the format parameters for a variable sized disk |
202 __PRINT1(_L(" ::InitializeFormatDataL() err:%d"), nRes); |
204 |
203 User::Leave(nRes); |
205 @param aDiskSizeInSectors volume size in sectors |
204 } |
206 @return standard error code |
205 |
207 */ |
206 } |
208 TInt CFatFormatCB::InitFormatDataForVariableSizeDisk(TUint aDiskSizeInSectors) |
207 |
209 { |
|
210 iNumberOfFats=2; // 1 FAT 1 Indirection table (FIT) |
|
211 iReservedSectors=1; |
|
212 iRootDirEntries=2*(4*KDefaultSectorSize)/sizeof(SFatDirEntry); |
|
213 TUint minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; |
|
214 iSectorsPerCluster=1; |
|
215 |
|
216 while (minSectorsPerCluster>iSectorsPerCluster) |
|
217 iSectorsPerCluster<<=1; |
|
218 |
|
219 __PRINT1(_L("iSectorsPerCluster = %d"),iSectorsPerCluster); |
|
220 iSectorsPerFat=MaxFat16Sectors(); |
|
221 __PRINT1(_L("iSectorsPerFat = %d"),iSectorsPerFat); |
|
222 iFileSystemName=KFileSystemName16; |
|
223 |
|
224 return KErrNone; |
|
225 } |
|
226 |
208 |
227 TInt CFatFormatCB::HandleCorrupt(TInt aError) |
209 TInt CFatFormatCB::HandleCorrupt(TInt aError) |
228 // |
210 // |
229 // Handle disk corrupt during format. It needs media driver's support. |
211 // Handle disk corrupt during format. It needs media driver's support. |
230 // Media driver should handle DLocalDrive::EGetLastErrorInfo request in |
212 // Media driver should handle DLocalDrive::EGetLastErrorInfo request in |
231 // its Request function, filling in proper error information. |
213 // its Request function, filling in proper error information. |
232 // @see TErrorInfo |
214 // @see TErrorInfo |
233 // |
215 // |
234 { |
216 { |
235 __PRINT2(_L("CFatFormatCB::HandleCorrupt(%d) drv:%d"), aError, Drive().DriveNumber()); |
217 __PRINT2(_L("CFatFormatCB::HandleCorrupt(%d) drv:%d"), aError, Drive().DriveNumber()); |
236 |
218 |
237 TPckgBuf<TErrorInfo> info; |
219 TPckgBuf<TErrorInfo> info; |
238 TInt r = LocalDrive()->GetLastErrorInfo(info); |
220 TInt r = LocalDrive()->GetLastErrorInfo(info); |
239 |
221 |
240 if(r != KErrNone) |
222 if(r != KErrNone) |
241 { |
223 { |
242 __PRINT1(_L("....GetLastErrorInfo() err:%d"), r); |
224 __PRINT1(_L("....GetLastErrorInfo() err:%d"), r); |
243 } |
225 } |
244 |
226 |
245 if (r == KErrNotSupported) |
227 if (r == KErrNotSupported) |
246 return KErrCorrupt; |
228 return KErrCorrupt; |
247 else if (r != KErrNone) |
229 else if (r != KErrNone) |
248 return r; |
230 return r; |
249 |
231 |
250 __PRINT3(_L("....TErrorInfo iReasonCode:%d, iErrorPos:%LU, iOtherInfo:%d"), info().iReasonCode, info().iErrorPos, info().iOtherInfo); |
232 __PRINT3(_L("....TErrorInfo iReasonCode:%d, iErrorPos:%LU, iOtherInfo:%d"), info().iReasonCode, info().iErrorPos, info().iOtherInfo); |
251 |
233 |
252 // if no error reported by GetLastErrorInfo(), return the original error |
234 // if no error reported by GetLastErrorInfo(), return the original error |
253 if (info().iReasonCode == KErrNone) |
235 if (info().iReasonCode == KErrNone) |
254 return aError; |
236 return aError; |
255 |
237 |
256 if (info().iReasonCode!=KErrNone && info().iReasonCode!=TErrorInfo::EBadSector) |
238 if (info().iReasonCode!=KErrNone && info().iReasonCode!=TErrorInfo::EBadSector) |
257 return info().iReasonCode; |
239 return info().iReasonCode; |
258 |
240 |
259 // First bad sector met |
241 // First bad sector met |