sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // CMassStorageMountCB implementation. sl@0: // sl@0: // sl@0: sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include sl@0: sl@0: #include "mstypes.h" sl@0: #include "msctypes.h" sl@0: sl@0: #include "cmassstoragefilesystem.h" sl@0: #include "drivemanager.h" sl@0: sl@0: sl@0: #include "cusbmassstoragecontroller.h" sl@0: #include "cmassstoragemountcb.h" sl@0: #include "debug.h" sl@0: sl@0: CMassStorageMountCB::CMassStorageMountCB(const TLunToDriveMap& aDriveMapping) sl@0: : iDriveMapping(aDriveMapping) sl@0: { sl@0: } sl@0: sl@0: CMassStorageMountCB* CMassStorageMountCB::NewL(const TLunToDriveMap& aDriveMapping) sl@0: { sl@0: return new (ELeave) CMassStorageMountCB(aDriveMapping); sl@0: } sl@0: sl@0: /** sl@0: Checks that the drive number is supported. sl@0: sl@0: @leave KErrNotReady The drive number is not supported. sl@0: */ sl@0: TInt CMassStorageMountCB::CheckDriveNumberL() sl@0: { sl@0: __FNLOG("CMassStorageMountCB::CheckDriveNumberL"); sl@0: TInt driveNumber; sl@0: driveNumber = Drive().DriveNumber(); sl@0: if (!IsValidLocalDriveMapping(driveNumber)) sl@0: { sl@0: __PRINT1(_L("CMassStorageMountCB::CheckDriveNumberL: Drive number %d not supported"), driveNumber); sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: __PRINT1(_L("CMassStorageMountCB::CheckDriveNumberL: Drive number = %d"), driveNumber); sl@0: return driveNumber; sl@0: } sl@0: sl@0: /** sl@0: Registers the drive with the Mass Storage drive manager. sl@0: sl@0: @leave KErrNotSupported The drive is not compatible with Mass Storage. sl@0: */ sl@0: void CMassStorageMountCB::MountL(TBool /*aForceMount*/) sl@0: { sl@0: __FNLOG("CMassStorageMountCB::MountL"); sl@0: sl@0: CheckDriveNumberL(); sl@0: CMassStorageFileSystem& msFsys = *reinterpret_cast(Drive().GetFSys()); sl@0: sl@0: TInt lun = DriveNumberToLun(Drive().DriveNumber()); sl@0: sl@0: if(lun < 0) sl@0: { sl@0: // This is not a supported Mass Storage drive sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: TBusLocalDrive& localDrive = msFsys.iMediaChangedStatusList[lun].iLocalDrive; sl@0: sl@0: TInt err = CreateLocalDrive(localDrive); sl@0: User::LeaveIfError(err); sl@0: sl@0: CProxyDrive* proxyDrive = LocalDrive(); sl@0: sl@0: TLocalDriveCapsV2Buf caps; sl@0: err = localDrive.Caps(caps); sl@0: sl@0: //Make sure file system is FAT and removable sl@0: if (err == KErrNone) sl@0: { sl@0: err = KErrNotSupported; sl@0: if ((caps().iDriveAtt & KDriveAttRemovable) == KDriveAttRemovable) sl@0: { sl@0: if (caps().iType != EMediaNotPresent) sl@0: { sl@0: err = KErrNone; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (err != KErrNone && err != KErrNotReady) sl@0: { sl@0: __PRINT1(_L("CMassStorageMountCB::MountL: Drive is not compatible with Mass Storage, err=%d"), err); sl@0: User::Leave(err); sl@0: } sl@0: sl@0: __PRINT(_L("CMassStorageMountCB::MountL: Registering drive")); sl@0: // Set media changed to true so that Win2K doesn't used cached drive data sl@0: TBool& mediaChanged = msFsys.iMediaChangedStatusList[lun].iMediaChanged; sl@0: mediaChanged = ETrue; sl@0: msFsys.Controller().DriveManager().RegisterDriveL(*proxyDrive, mediaChanged, lun); sl@0: SetVolumeName(_L("MassStorage").AllocL()); sl@0: } sl@0: sl@0: /** sl@0: Returns the LUN that corresponds to the specified drive number. sl@0: sl@0: @param aDriveNumber The drive number. sl@0: */ sl@0: TInt CMassStorageMountCB::DriveNumberToLun(TInt aDriveNumber) sl@0: { sl@0: __FNLOG("CMassStorageMountCB::DriveNumberToLun"); sl@0: TInt lun = -1; sl@0: for (TInt i = 0; i < iDriveMapping.Count(); i++) sl@0: { sl@0: if (iDriveMapping[i] == aDriveNumber) sl@0: { sl@0: lun = i; sl@0: break; sl@0: } sl@0: } sl@0: __PRINT2(_L("CMassStorageMountCB::DriveNumberToLun: Drive %d maps to LUN %d"), aDriveNumber, lun); sl@0: return lun; sl@0: } sl@0: sl@0: /** sl@0: Deregisters the drive from the Drive Manager. sl@0: */ sl@0: void CMassStorageMountCB::Dismounted() sl@0: { sl@0: __FNLOG("CMassStorageMountCB::Dismounted"); sl@0: TInt driveNumber = -1; sl@0: TRAPD(err, driveNumber = CheckDriveNumberL()); sl@0: if (err != KErrNone) sl@0: { sl@0: return; sl@0: } sl@0: __PRINT(_L("CMassStorageMountCB::Dismounted: Deregistering drive")); sl@0: CMassStorageFileSystem& msFsys = *reinterpret_cast(Drive().GetFSys()); sl@0: msFsys.Controller().DriveManager().DeregisterDrive(DriveNumberToLun(driveNumber)); sl@0: sl@0: DismountedLocalDrive(); sl@0: } sl@0: sl@0: /** sl@0: Unlocks the drive with the specified password, optionally storing the password for later use. sl@0: sl@0: @param aPassword The password to use for unlocking the drive. sl@0: @param aStore True if the password is to be stored. sl@0: */ sl@0: TInt CMassStorageMountCB::Unlock(TMediaPassword& aPassword, TBool aStore) sl@0: { sl@0: __FNLOG("CMassStorageMountCB::Unlock"); sl@0: TInt driveNumber = -1; sl@0: TRAPD(err, driveNumber = CheckDriveNumberL()); sl@0: if (err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: TBusLocalDrive& localDrive=GetLocalDrive(driveNumber); sl@0: if(localDrive.Status() == KErrLocked) sl@0: { sl@0: localDrive.Status() = KErrNotReady; sl@0: } sl@0: TInt r = localDrive.Unlock(aPassword, aStore); sl@0: if(r == KErrNone && aStore) sl@0: { sl@0: WritePasswordData(); sl@0: } sl@0: return(r); sl@0: } sl@0: sl@0: /** sl@0: Stores the password for the drive to the password file. sl@0: */ sl@0: void CMassStorageMountCB::WritePasswordData() sl@0: { sl@0: __FNLOG("CMassStorageMountCB::WritePasswordData"); sl@0: TBusLocalDrive& local=GetLocalDrive(Drive().DriveNumber()); sl@0: TInt length = local.PasswordStoreLengthInBytes(); sl@0: if(length==0) sl@0: { sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: WriteToDisk(mediaPWrdFile,_L8("")); sl@0: return; sl@0: } sl@0: HBufC8* hDes=HBufC8::New(length); sl@0: if(hDes==NULL) sl@0: { sl@0: return; sl@0: } sl@0: TPtr8 pDes=hDes->Des(); sl@0: TInt r=local.ReadPasswordData(pDes); sl@0: if(r==KErrNone) sl@0: { sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: WriteToDisk(mediaPWrdFile,pDes); sl@0: } sl@0: delete hDes; sl@0: } sl@0: sl@0: /** sl@0: Make sure that the file system is fat. sl@0: */ sl@0: TBool CMassStorageMountCB::ValidateBootSector() sl@0: { sl@0: __FNLOG("CMassStorageMountCB::ValidateBootSector"); sl@0: sl@0: TFatBootSector bootSector; sl@0: TInt r=ReadBootSector(bootSector); sl@0: __PRINT1(_L("CMassStorageMountCB::MountL - ReadBootSector returned %d"),r); sl@0: if (r != KErrNone) sl@0: { sl@0: return EFalse; sl@0: } sl@0: sl@0: __PRINT(_L("\nBootSector info")); sl@0: __PRINT8BIT1(_L("FAT type = %S"),bootSector.FileSysType()); sl@0: __PRINT8BIT1(_L("Vendor ID = %S"),bootSector.VendorId()); sl@0: __PRINT1(_L("BytesPerSector %d"),bootSector.BytesPerSector()); sl@0: __PRINT1(_L("SectorsPerCluster %d"),bootSector.SectorsPerCluster()); sl@0: __PRINT1(_L("ReservedSectors %d"),bootSector.ReservedSectors()); sl@0: __PRINT1(_L("NumberOfFats %d"),bootSector.NumberOfFats()); sl@0: __PRINT1(_L("RootDirEntries %d"),bootSector.RootDirEntries()); sl@0: __PRINT1(_L("Total Sectors = %d"),bootSector.TotalSectors()); sl@0: __PRINT1(_L("MediaDescriptor = 0x%x"),bootSector.MediaDescriptor()); sl@0: __PRINT1(_L("FatSectors %d"),bootSector.FatSectors()); sl@0: __PRINT1(_L("SectorsPerTrack %d"),bootSector.SectorsPerTrack()); sl@0: __PRINT1(_L("NumberOfHeads %d"),bootSector.NumberOfHeads()); sl@0: __PRINT1(_L("HugeSectors %d"),bootSector.HugeSectors()); sl@0: __PRINT1(_L("Fat32 Sectors %d"),bootSector.FatSectors32()); sl@0: __PRINT1(_L("Fat32 Flags %d"),bootSector.FATFlags()); sl@0: __PRINT1(_L("Fat32 Version Number %d"),bootSector.VersionNumber()); sl@0: __PRINT1(_L("Root Cluster Number %d"),bootSector.RootClusterNum()); sl@0: __PRINT1(_L("FSInfo Sector Number %d"),bootSector.FSInfoSectorNum()); sl@0: __PRINT1(_L("Backup Boot Rec Sector Number %d"),bootSector.BkBootRecSector()); sl@0: __PRINT1(_L("PhysicalDriveNumber %d"),bootSector.PhysicalDriveNumber()); sl@0: __PRINT1(_L("ExtendedBootSignature %d"),bootSector.ExtendedBootSignature()); sl@0: __PRINT1(_L("UniqueID %d"),bootSector.UniqueID()); sl@0: __PRINT8BIT1(_L("VolumeLabel %S"),bootSector.VolumeLabel()); sl@0: __PRINT8BIT1(_L("FileSysType %S\n"),bootSector.FileSysType()); sl@0: sl@0: iUniqueID=bootSector.UniqueID(); sl@0: iIs16BitFat=bootSector.Is16BitFat(); sl@0: sl@0: iIs32BitFat=bootSector.Is32BitFat(); sl@0: switch (DetermineFatType(bootSector)) sl@0: { sl@0: case 12: sl@0: iIs16BitFat = EFalse; sl@0: iIs32BitFat = EFalse; sl@0: break; sl@0: case 16: sl@0: iIs16BitFat = ETrue; sl@0: iIs32BitFat = EFalse; sl@0: break; sl@0: case 32: sl@0: iIs16BitFat = EFalse; sl@0: iIs32BitFat = ETrue; sl@0: break; sl@0: default: sl@0: return EFalse; sl@0: } sl@0: sl@0: TInt sectorsPerCluster=bootSector.SectorsPerCluster(); sl@0: if (!IsPowerOfTwo(sectorsPerCluster)) sl@0: return EFalse; sl@0: sl@0: TInt sectorSizeLog2=Log2(bootSector.BytesPerSector()); sl@0: if (sectorSizeLog2<0 || !IsPowerOfTwo(bootSector.BytesPerSector())) sl@0: return EFalse; sl@0: sl@0: TInt firstFatSector=bootSector.ReservedSectors(); sl@0: if (firstFatSector<1) sl@0: return EFalse; sl@0: sl@0: TInt fatSizeInBytes; sl@0: if(iIs32BitFat) sl@0: { sl@0: fatSizeInBytes=bootSector.FatSectors32()*bootSector.BytesPerSector(); sl@0: if (fatSizeInBytes>sectorSizeLog2; sl@0: TInt rootDirEnd=(rootDirectorySector+numOfRootDirSectors)<Read(0,KSizeOfFatBootSector,buf); sl@0: if (r!=KErrNone) sl@0: { sl@0: __PRINT1(_L("LocalDrive::Read() failed - %d"),r); sl@0: return(r); sl@0: } sl@0: // 0 TUint8 iJumpInstruction[3] sl@0: Mem::Copy(&aBootSector.iJumpInstruction,&data[pos],3); sl@0: pos+=3; sl@0: // 3 TUint8 iVendorId[KVendorIdSize] sl@0: Mem::Copy(&aBootSector.iVendorId,&data[pos],KVendorIdSize); sl@0: pos+=KVendorIdSize; sl@0: // 11 TUint16 iBytesPerSector sl@0: Mem::Copy(&aBootSector.iBytesPerSector,&data[pos],2); sl@0: pos+=2; sl@0: // 13 TUint8 sectorsPerCluster sl@0: Mem::Copy(&aBootSector.iSectorsPerCluster,&data[pos],1); sl@0: pos+=1; sl@0: // 14 TUint16 iReservedSectors sl@0: Mem::Copy(&aBootSector.iReservedSectors,&data[pos],2); sl@0: pos+=2; sl@0: // 16 TUint8 numberOfFats sl@0: Mem::Copy(&aBootSector.iNumberOfFats,&data[pos],1); sl@0: pos+=1; sl@0: // 17 TUint16 iRootDirEntries sl@0: Mem::Copy(&aBootSector.iRootDirEntries,&data[pos],2); sl@0: pos+=2; sl@0: // 19 TUint16 totalSectors sl@0: Mem::Copy(&aBootSector.iTotalSectors,&data[pos],2); sl@0: pos+=2; sl@0: // 21 TUint8 iMediaDescriptor sl@0: Mem::Copy(&aBootSector.iMediaDescriptor,&data[pos],1); sl@0: pos+=1; sl@0: // 22 TUint16 iFatSectors sl@0: Mem::Copy(&aBootSector.iFatSectors,&data[pos],2); sl@0: pos+=2; sl@0: // 24 TUint16 iSectorsPerTrack sl@0: Mem::Copy(&aBootSector.iSectorsPerTrack,&data[pos],2); sl@0: pos+=2; sl@0: // 26 TUint16 iNumberOfHeads sl@0: Mem::Copy(&aBootSector.iNumberOfHeads,&data[pos],2); sl@0: pos+=2; sl@0: // 28 TUint32 iHiddenSectors sl@0: Mem::Copy(&aBootSector.iHiddenSectors,&data[pos],4); sl@0: pos+=4; sl@0: // 32 TUint32 iHugeSectors sl@0: Mem::Copy(&aBootSector.iHugeSectors,&data[pos],4); sl@0: pos+=4; sl@0: sl@0: if(aBootSector.iRootDirEntries == 0) //indicates we have FAT32 volume sl@0: { sl@0: __PRINT(_L("\nFile system thinks Fat32")); sl@0: sl@0: //36 TUint32 iFatSectors32 sl@0: Mem::Copy(&aBootSector.iFatSectors32, &data[pos],4); sl@0: pos+=4; sl@0: //40 TUint16 iFATFlags sl@0: Mem::Copy(&aBootSector.iFATFlags, &data[pos],2); sl@0: pos+=2; sl@0: //42 TUint16 iVersionNumber sl@0: Mem::Copy(&aBootSector.iVersionNumber, &data[pos],2); sl@0: pos+=2; sl@0: //44 TUint32 iRootClusterNum sl@0: Mem::Copy(&aBootSector.iRootClusterNum, &data[pos],4); sl@0: pos+=4; sl@0: //48 TUint16 iFSInfoSectorNum sl@0: Mem::Copy(&aBootSector.iFSInfoSectorNum, &data[pos],2); sl@0: pos+=2; sl@0: //50 TUint16 iBkBootRecSector sl@0: Mem::Copy(&aBootSector.iBkBootRecSector, &data[pos],2); sl@0: pos+=(2+12);//extra 12 for the reserved bytes sl@0: } sl@0: sl@0: // 36|64 TUint8 iPhysicalDriveNumber sl@0: Mem::Copy(&aBootSector.iPhysicalDriveNumber,&data[pos],1); sl@0: pos+=1; sl@0: // 37|65 TUint8 iReserved sl@0: Mem::Copy(&aBootSector.iReserved,&data[pos],1); sl@0: pos+=1; sl@0: // 38|66 TUint8 iExtendedBootSignature sl@0: Mem::Copy(&aBootSector.iExtendedBootSignature,&data[pos],1); sl@0: pos+=1; sl@0: // 39|67 TUint32 iUniqueID sl@0: Mem::Copy(&aBootSector.iUniqueID,&data[pos],4); sl@0: pos+=4; sl@0: // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize] sl@0: Mem::Copy(&aBootSector.iVolumeLabel,&data[pos],KVolumeLabelSize); sl@0: pos+=KVolumeLabelSize; sl@0: // 54|82 TUint8 iFileSysType[KFileSysTypeSize] sl@0: Mem::Copy(&aBootSector.iFileSysType,&data[pos],KFileSysTypeSize); sl@0: // 62|90 sl@0: sl@0: return(KErrNone); sl@0: } sl@0: sl@0: /** sl@0: Work out if we have a FAT12|16|32 volume. sl@0: Returns 12, 16 or 32 as appropriate. sl@0: Returns 0 if can't be calculated (invalid values) sl@0: */ sl@0: TInt CMassStorageMountCB::DetermineFatType(TFatBootSector& aBootSector) sl@0: { sl@0: TUint32 ressectors = aBootSector.ReservedSectors(); sl@0: sl@0: if (aBootSector.SectorsPerCluster() < 1) sl@0: return 0; sl@0: sl@0: if (aBootSector.RootDirEntries() != 0) sl@0: { sl@0: TUint32 rootdirbytes; sl@0: rootdirbytes = aBootSector.RootDirEntries() * 32 + aBootSector.BytesPerSector() - 1; sl@0: ressectors += rootdirbytes / aBootSector.BytesPerSector(); sl@0: } sl@0: sl@0: if (aBootSector.FatSectors() != 0) sl@0: ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors(); sl@0: else sl@0: ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors32(); sl@0: sl@0: TUint32 totalsectors; sl@0: if (aBootSector.TotalSectors() != 0) sl@0: totalsectors = aBootSector.TotalSectors(); sl@0: else sl@0: totalsectors = aBootSector.HugeSectors(); sl@0: sl@0: if (ressectors < 1 || totalsectors < 1) sl@0: return 0; sl@0: sl@0: TUint32 datasec; sl@0: datasec = totalsectors - ressectors; sl@0: sl@0: TUint32 countofclusters; sl@0: countofclusters = datasec / aBootSector.SectorsPerCluster(); sl@0: sl@0: __PRINT1(_L("CFatMountCB: Count of clusters = %d\n"), countofclusters); sl@0: sl@0: if (countofclusters < 4085) sl@0: { sl@0: return 12; sl@0: } sl@0: else if (countofclusters < 65525) sl@0: { sl@0: return 16; sl@0: } sl@0: else sl@0: { sl@0: return 32; sl@0: } sl@0: } sl@0: sl@0: TInt CMassStorageMountCB::ReMount() sl@0: { sl@0: RDebug::Printf("CMassStorageMountCB::ReMount()"); sl@0: return KErrNotReady; sl@0: } sl@0: sl@0: void CMassStorageMountCB::VolumeL(TVolumeInfo& /*aVolume*/) const sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::SetVolumeL(TDes& /*aName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::MkDirL(const TDesC& /*aName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::RmDirL(const TDesC& /*aName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::DeleteL(const TDesC& /*aName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::EntryL(const TDesC& /*aName*/,TEntry& /*anEntry*/) const sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::FileOpenL(const TDesC& /*aName*/,TUint /*aMode*/,TFileOpen /*anOpen*/,CFileCB* /*aFile*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::DirOpenL(const TDesC& /*aName*/,CDirCB* /*aDir*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: sl@0: void CMassStorageMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aTrg*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: sl@0: void CMassStorageMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: void CMassStorageMountCB::GetLongNameL(const TDesC& /*aShorName*/,TDes& /*aLongName*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: #if defined(_DEBUG) sl@0: TInt CMassStorageMountCB::ControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2) sl@0: // sl@0: // Debug function sl@0: // sl@0: { sl@0: if(aCommand>=(KMaxTInt/2)) sl@0: return LocalDrive()->ControlIO(aMessage,aCommand-(KMaxTInt/2),aParam1,aParam2); sl@0: else sl@0: return KErrNotSupported; sl@0: } sl@0: #else sl@0: TInt CMassStorageMountCB::ControlIO(const RMessagePtr2& /*aMessage*/,TInt /*aCommand*/,TAny* /*aParam1*/,TAny* /*aParam2*/) sl@0: {return(KErrNotSupported);} sl@0: #endif sl@0: sl@0: void CMassStorageMountCB::ReadSectionL(const TDesC& /*aName*/,TInt /*aPos*/,TAny* /*aTrg*/,TInt /*aLength*/,const RMessagePtr2& /*aMessage*/) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: /** sl@0: Returns ETrue if aNum is a power of two sl@0: */ sl@0: TBool CMassStorageMountCB::IsPowerOfTwo(TInt aNum) sl@0: { sl@0: sl@0: if (aNum==0) sl@0: return(EFalse); sl@0: sl@0: while(aNum) sl@0: { sl@0: if (aNum & 0x01) sl@0: { sl@0: if (aNum>>1) sl@0: return EFalse; sl@0: break; sl@0: } sl@0: aNum>>=1; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: /** sl@0: Returns the position of the highest bit in aNum or -1 if aNum == 0 sl@0: */ sl@0: TInt CMassStorageMountCB::Log2(TInt aNum) sl@0: { sl@0: sl@0: TInt res=-1; sl@0: while(aNum) sl@0: { sl@0: res++; sl@0: aNum>>=1; sl@0: } sl@0: return(res); sl@0: }