218 WriteToDisk(mediaPWrdFile,pDes); |
218 WriteToDisk(mediaPWrdFile,pDes); |
219 } |
219 } |
220 delete hDes; |
220 delete hDes; |
221 } |
221 } |
222 |
222 |
223 /** |
|
224 Make sure that the file system is fat. |
|
225 */ |
|
226 TBool CMassStorageMountCB::ValidateBootSector() |
|
227 { |
|
228 __FNLOG("CMassStorageMountCB::ValidateBootSector"); |
|
229 |
|
230 TFatBootSector bootSector; |
|
231 TInt r=ReadBootSector(bootSector); |
|
232 __PRINT1(_L("CMassStorageMountCB::MountL - ReadBootSector returned %d"),r); |
|
233 if (r != KErrNone) |
|
234 { |
|
235 return EFalse; |
|
236 } |
|
237 |
|
238 __PRINT(_L("\nBootSector info")); |
|
239 __PRINT8BIT1(_L("FAT type = %S"),bootSector.FileSysType()); |
|
240 __PRINT8BIT1(_L("Vendor ID = %S"),bootSector.VendorId()); |
|
241 __PRINT1(_L("BytesPerSector %d"),bootSector.BytesPerSector()); |
|
242 __PRINT1(_L("SectorsPerCluster %d"),bootSector.SectorsPerCluster()); |
|
243 __PRINT1(_L("ReservedSectors %d"),bootSector.ReservedSectors()); |
|
244 __PRINT1(_L("NumberOfFats %d"),bootSector.NumberOfFats()); |
|
245 __PRINT1(_L("RootDirEntries %d"),bootSector.RootDirEntries()); |
|
246 __PRINT1(_L("Total Sectors = %d"),bootSector.TotalSectors()); |
|
247 __PRINT1(_L("MediaDescriptor = 0x%x"),bootSector.MediaDescriptor()); |
|
248 __PRINT1(_L("FatSectors %d"),bootSector.FatSectors()); |
|
249 __PRINT1(_L("SectorsPerTrack %d"),bootSector.SectorsPerTrack()); |
|
250 __PRINT1(_L("NumberOfHeads %d"),bootSector.NumberOfHeads()); |
|
251 __PRINT1(_L("HugeSectors %d"),bootSector.HugeSectors()); |
|
252 __PRINT1(_L("Fat32 Sectors %d"),bootSector.FatSectors32()); |
|
253 __PRINT1(_L("Fat32 Flags %d"),bootSector.FATFlags()); |
|
254 __PRINT1(_L("Fat32 Version Number %d"),bootSector.VersionNumber()); |
|
255 __PRINT1(_L("Root Cluster Number %d"),bootSector.RootClusterNum()); |
|
256 __PRINT1(_L("FSInfo Sector Number %d"),bootSector.FSInfoSectorNum()); |
|
257 __PRINT1(_L("Backup Boot Rec Sector Number %d"),bootSector.BkBootRecSector()); |
|
258 __PRINT1(_L("PhysicalDriveNumber %d"),bootSector.PhysicalDriveNumber()); |
|
259 __PRINT1(_L("ExtendedBootSignature %d"),bootSector.ExtendedBootSignature()); |
|
260 __PRINT1(_L("UniqueID %d"),bootSector.UniqueID()); |
|
261 __PRINT8BIT1(_L("VolumeLabel %S"),bootSector.VolumeLabel()); |
|
262 __PRINT8BIT1(_L("FileSysType %S\n"),bootSector.FileSysType()); |
|
263 |
|
264 iUniqueID=bootSector.UniqueID(); |
|
265 iIs16BitFat=bootSector.Is16BitFat(); |
|
266 |
|
267 iIs32BitFat=bootSector.Is32BitFat(); |
|
268 switch (DetermineFatType(bootSector)) |
|
269 { |
|
270 case 12: |
|
271 iIs16BitFat = EFalse; |
|
272 iIs32BitFat = EFalse; |
|
273 break; |
|
274 case 16: |
|
275 iIs16BitFat = ETrue; |
|
276 iIs32BitFat = EFalse; |
|
277 break; |
|
278 case 32: |
|
279 iIs16BitFat = EFalse; |
|
280 iIs32BitFat = ETrue; |
|
281 break; |
|
282 default: |
|
283 return EFalse; |
|
284 } |
|
285 |
|
286 TInt sectorsPerCluster=bootSector.SectorsPerCluster(); |
|
287 if (!IsPowerOfTwo(sectorsPerCluster)) |
|
288 return EFalse; |
|
289 |
|
290 TInt sectorSizeLog2=Log2(bootSector.BytesPerSector()); |
|
291 if (sectorSizeLog2<0 || !IsPowerOfTwo(bootSector.BytesPerSector())) |
|
292 return EFalse; |
|
293 |
|
294 TInt firstFatSector=bootSector.ReservedSectors(); |
|
295 if (firstFatSector<1) |
|
296 return EFalse; |
|
297 |
|
298 TInt fatSizeInBytes; |
|
299 if(iIs32BitFat) |
|
300 { |
|
301 fatSizeInBytes=bootSector.FatSectors32()*bootSector.BytesPerSector(); |
|
302 if (fatSizeInBytes<bootSector.BytesPerSector()) |
|
303 return EFalse; |
|
304 } |
|
305 else |
|
306 { |
|
307 fatSizeInBytes=bootSector.FatSectors()*bootSector.BytesPerSector(); |
|
308 if (fatSizeInBytes<bootSector.BytesPerSector()) |
|
309 return EFalse; |
|
310 |
|
311 TInt rootDirectorySector=firstFatSector+bootSector.FatSectors()*bootSector.NumberOfFats(); |
|
312 if (rootDirectorySector<3) |
|
313 return EFalse; |
|
314 |
|
315 TInt rootDirSizeInBytes=bootSector.RootDirEntries()*KSizeOfFatDirEntry; |
|
316 TInt numOfRootDirSectors=(rootDirSizeInBytes+(1<<sectorSizeLog2)-1)>>sectorSizeLog2; |
|
317 TInt rootDirEnd=(rootDirectorySector+numOfRootDirSectors)<<sectorSizeLog2; |
|
318 if (rootDirEnd<(4<<sectorSizeLog2)) |
|
319 return EFalse; |
|
320 } |
|
321 |
|
322 |
|
323 TInt totalSectors=bootSector.TotalSectors(); |
|
324 if (totalSectors==0) |
|
325 totalSectors=bootSector.HugeSectors(); |
|
326 if (totalSectors<5) |
|
327 return EFalse; |
|
328 |
|
329 TInt numberOfFats=bootSector.NumberOfFats(); |
|
330 if (numberOfFats<1) |
|
331 return EFalse; |
|
332 |
|
333 return ETrue; |
|
334 } |
|
335 |
|
336 /** |
|
337 Read non aligned boot data from media into TFatBootSector structure |
|
338 |
|
339 @param aBootSector refrence to TFatBootSector populate |
|
340 @return Media read error code |
|
341 */ |
|
342 TInt CMassStorageMountCB::ReadBootSector(TFatBootSector& aBootSector) |
|
343 { |
|
344 __FNLOG("CMassStorageMountCB::ReadBootSector"); |
|
345 TInt pos=0; |
|
346 TUint8 data[KSizeOfFatBootSector]; |
|
347 TPtr8 buf(&data[0],KSizeOfFatBootSector); |
|
348 TInt r=LocalDrive()->Read(0,KSizeOfFatBootSector,buf); |
|
349 if (r!=KErrNone) |
|
350 { |
|
351 __PRINT1(_L("LocalDrive::Read() failed - %d"),r); |
|
352 return(r); |
|
353 } |
|
354 // 0 TUint8 iJumpInstruction[3] |
|
355 Mem::Copy(&aBootSector.iJumpInstruction,&data[pos],3); |
|
356 pos+=3; |
|
357 // 3 TUint8 iVendorId[KVendorIdSize] |
|
358 Mem::Copy(&aBootSector.iVendorId,&data[pos],KVendorIdSize); |
|
359 pos+=KVendorIdSize; |
|
360 // 11 TUint16 iBytesPerSector |
|
361 Mem::Copy(&aBootSector.iBytesPerSector,&data[pos],2); |
|
362 pos+=2; |
|
363 // 13 TUint8 sectorsPerCluster |
|
364 Mem::Copy(&aBootSector.iSectorsPerCluster,&data[pos],1); |
|
365 pos+=1; |
|
366 // 14 TUint16 iReservedSectors |
|
367 Mem::Copy(&aBootSector.iReservedSectors,&data[pos],2); |
|
368 pos+=2; |
|
369 // 16 TUint8 numberOfFats |
|
370 Mem::Copy(&aBootSector.iNumberOfFats,&data[pos],1); |
|
371 pos+=1; |
|
372 // 17 TUint16 iRootDirEntries |
|
373 Mem::Copy(&aBootSector.iRootDirEntries,&data[pos],2); |
|
374 pos+=2; |
|
375 // 19 TUint16 totalSectors |
|
376 Mem::Copy(&aBootSector.iTotalSectors,&data[pos],2); |
|
377 pos+=2; |
|
378 // 21 TUint8 iMediaDescriptor |
|
379 Mem::Copy(&aBootSector.iMediaDescriptor,&data[pos],1); |
|
380 pos+=1; |
|
381 // 22 TUint16 iFatSectors |
|
382 Mem::Copy(&aBootSector.iFatSectors,&data[pos],2); |
|
383 pos+=2; |
|
384 // 24 TUint16 iSectorsPerTrack |
|
385 Mem::Copy(&aBootSector.iSectorsPerTrack,&data[pos],2); |
|
386 pos+=2; |
|
387 // 26 TUint16 iNumberOfHeads |
|
388 Mem::Copy(&aBootSector.iNumberOfHeads,&data[pos],2); |
|
389 pos+=2; |
|
390 // 28 TUint32 iHiddenSectors |
|
391 Mem::Copy(&aBootSector.iHiddenSectors,&data[pos],4); |
|
392 pos+=4; |
|
393 // 32 TUint32 iHugeSectors |
|
394 Mem::Copy(&aBootSector.iHugeSectors,&data[pos],4); |
|
395 pos+=4; |
|
396 |
|
397 if(aBootSector.iRootDirEntries == 0) //indicates we have FAT32 volume |
|
398 { |
|
399 __PRINT(_L("\nFile system thinks Fat32")); |
|
400 |
|
401 //36 TUint32 iFatSectors32 |
|
402 Mem::Copy(&aBootSector.iFatSectors32, &data[pos],4); |
|
403 pos+=4; |
|
404 //40 TUint16 iFATFlags |
|
405 Mem::Copy(&aBootSector.iFATFlags, &data[pos],2); |
|
406 pos+=2; |
|
407 //42 TUint16 iVersionNumber |
|
408 Mem::Copy(&aBootSector.iVersionNumber, &data[pos],2); |
|
409 pos+=2; |
|
410 //44 TUint32 iRootClusterNum |
|
411 Mem::Copy(&aBootSector.iRootClusterNum, &data[pos],4); |
|
412 pos+=4; |
|
413 //48 TUint16 iFSInfoSectorNum |
|
414 Mem::Copy(&aBootSector.iFSInfoSectorNum, &data[pos],2); |
|
415 pos+=2; |
|
416 //50 TUint16 iBkBootRecSector |
|
417 Mem::Copy(&aBootSector.iBkBootRecSector, &data[pos],2); |
|
418 pos+=(2+12);//extra 12 for the reserved bytes |
|
419 } |
|
420 |
|
421 // 36|64 TUint8 iPhysicalDriveNumber |
|
422 Mem::Copy(&aBootSector.iPhysicalDriveNumber,&data[pos],1); |
|
423 pos+=1; |
|
424 // 37|65 TUint8 iReserved |
|
425 Mem::Copy(&aBootSector.iReserved,&data[pos],1); |
|
426 pos+=1; |
|
427 // 38|66 TUint8 iExtendedBootSignature |
|
428 Mem::Copy(&aBootSector.iExtendedBootSignature,&data[pos],1); |
|
429 pos+=1; |
|
430 // 39|67 TUint32 iUniqueID |
|
431 Mem::Copy(&aBootSector.iUniqueID,&data[pos],4); |
|
432 pos+=4; |
|
433 // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize] |
|
434 Mem::Copy(&aBootSector.iVolumeLabel,&data[pos],KVolumeLabelSize); |
|
435 pos+=KVolumeLabelSize; |
|
436 // 54|82 TUint8 iFileSysType[KFileSysTypeSize] |
|
437 Mem::Copy(&aBootSector.iFileSysType,&data[pos],KFileSysTypeSize); |
|
438 // 62|90 |
|
439 |
|
440 return(KErrNone); |
|
441 } |
|
442 |
|
443 /** |
|
444 Work out if we have a FAT12|16|32 volume. |
|
445 Returns 12, 16 or 32 as appropriate. |
|
446 Returns 0 if can't be calculated (invalid values) |
|
447 */ |
|
448 TInt CMassStorageMountCB::DetermineFatType(TFatBootSector& aBootSector) |
|
449 { |
|
450 TUint32 ressectors = aBootSector.ReservedSectors(); |
|
451 |
|
452 if (aBootSector.SectorsPerCluster() < 1) |
|
453 return 0; |
|
454 |
|
455 if (aBootSector.RootDirEntries() != 0) |
|
456 { |
|
457 TUint32 rootdirbytes; |
|
458 rootdirbytes = aBootSector.RootDirEntries() * 32 + aBootSector.BytesPerSector() - 1; |
|
459 ressectors += rootdirbytes / aBootSector.BytesPerSector(); |
|
460 } |
|
461 |
|
462 if (aBootSector.FatSectors() != 0) |
|
463 ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors(); |
|
464 else |
|
465 ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors32(); |
|
466 |
|
467 TUint32 totalsectors; |
|
468 if (aBootSector.TotalSectors() != 0) |
|
469 totalsectors = aBootSector.TotalSectors(); |
|
470 else |
|
471 totalsectors = aBootSector.HugeSectors(); |
|
472 |
|
473 if (ressectors < 1 || totalsectors < 1) |
|
474 return 0; |
|
475 |
|
476 TUint32 datasec; |
|
477 datasec = totalsectors - ressectors; |
|
478 |
|
479 TUint32 countofclusters; |
|
480 countofclusters = datasec / aBootSector.SectorsPerCluster(); |
|
481 |
|
482 __PRINT1(_L("CFatMountCB: Count of clusters = %d\n"), countofclusters); |
|
483 |
|
484 if (countofclusters < 4085) |
|
485 { |
|
486 return 12; |
|
487 } |
|
488 else if (countofclusters < 65525) |
|
489 { |
|
490 return 16; |
|
491 } |
|
492 else |
|
493 { |
|
494 return 32; |
|
495 } |
|
496 } |
|
497 |
223 |
498 TInt CMassStorageMountCB::ReMount() |
224 TInt CMassStorageMountCB::ReMount() |
499 { |
225 { |
500 RDebug::Printf("CMassStorageMountCB::ReMount()"); |
226 RDebug::Printf("CMassStorageMountCB::ReMount()"); |
501 return KErrNotReady; |
227 return KErrNotReady; |