diff -r 6e96d2143d46 -r 060d0b1ab845 filemanager/src/inc/fmutils_s60.cpp --- a/filemanager/src/inc/fmutils_s60.cpp Tue Jul 06 14:06:28 2010 +0300 +++ b/filemanager/src/inc/fmutils_s60.cpp Wed Aug 18 09:39:39 2010 +0300 @@ -36,7 +36,8 @@ #include #include #include - +#include +#include #include #include @@ -46,6 +47,34 @@ #define BURCONFIGFILE "z:/private/2002BCC0/burconfig.xml" + +/*! + Used to get drive type for convenience. +*/ +FmDriverInfo::DriveType FmDriverInfo::driveType() +{ + FmDriverInfo::DriveType driveType; + if( mDriveState & FmDriverInfo::EDriveRemovable ) { + if( mDriveState & FmDriverInfo::EDriveMassStorage ) { + driveType = FmDriverInfo::EDriveTypeMassStorage; + } else if( mDriveState & FmDriverInfo::EDriveUsbMemory ) { + driveType = FmDriverInfo::EDriveTypeUsbMemory; + } else if( mDriveState & FmDriverInfo::EDriveRemote ){ + driveType = FmDriverInfo::EDriveTypeRemote; + } else { + driveType = FmDriverInfo::EDriveTypeMemoryCard; + } + } else if( mDriveState & FmDriverInfo::EDriveRom ) { + driveType = FmDriverInfo::EDriveTypeRom; + } else if( mDriveState & FmDriverInfo::EDriveRam ) { + driveType = FmDriverInfo::EDriveTypeRam; + } else { + driveType = FmDriverInfo::EDriveTypePhoneMemory; + } + + return driveType; +} + QString FmUtils::getDriveNameFromPath( const QString &path ) { // fillPathWithSplash make sure path length will be at least 3 if it is not empty. @@ -94,7 +123,7 @@ } } - if( volumeName == KErrNone || driveInfoErr == KErrNone ) { + if( volumeInfoErr == KErrNone || driveInfoErr == KErrNone ) { //TDriveInfo driveInfo = volumeInfo.iDrive; quint32 drvStatus( 0 ); @@ -112,7 +141,12 @@ { state |= FmDriverInfo::EDriveUsbMemory; } - + + if ( drvStatus & DriveInfo::EDriveRemote ) + { + state |= FmDriverInfo::EDriveRemote; + } + if ( drvStatus & DriveInfo::EDriveRom ){ state |= FmDriverInfo::EDriveRom; } @@ -195,7 +229,7 @@ "_driveInfoErr:" + QString::number( driveInfoErr ) + "_errorCode:" + QString::number( errorCode ) + "_driveSatus:" + QString::number( state ) ); - FmLogger::log( logString ); + FM_LOG( logString ); return FmDriverInfo( volumeInfo.iSize, volumeInfo.iFree, driverName, volumeName, state ); } @@ -214,20 +248,20 @@ int FmUtils::removeDrivePwd( const QString &driverName, const QString &Pwd ) { - if( driverName.isEmpty() ) { + if( driverName.isEmpty() || Pwd.length() > FmMaxLengthofDrivePassword ) { return FmErrWrongParam; } QString logString = "Drive name:" + driverName; - FmLogger::log( logString ); + FM_LOG( logString ); logString = "Password:" + Pwd; - FmLogger::log( logString ); + FM_LOG( logString ); CCoeEnv *env = CCoeEnv::Static(); RFs& fs = env->FsSession(); TInt drive = 0; - drive = driverName[0].toUpper().toAscii() - 'A' + EDriveA; + drive = driverName[0].toUpper().toAscii() - 'A' + EDriveA; HBufC* password16 = XQConversions::qStringToS60Desc( Pwd ); TMediaPassword password; @@ -237,10 +271,12 @@ int err( fs.ClearPassword( drive, password ) ); logString = "Drive:" + QString::number( drive ); - FmLogger::log( logString ); + FM_LOG( logString ); logString = "Clear password error:" + QString::number( err ); - FmLogger::log( logString ); + FM_LOG( logString ); + + delete password16; if( err == KErrNone ){ return FmErrNone; @@ -255,13 +291,13 @@ int FmUtils::unlockDrive( const QString &driverName, const QString &Pwd ) { - if( driverName.isEmpty() ) { + if( driverName.isEmpty() || Pwd.length() > FmMaxLengthofDrivePassword ) { return FmErrWrongParam; } QString logString = "Drive name:" + driverName; - FmLogger::log( logString ); + FM_LOG( logString ); logString = "Password:" + Pwd; - FmLogger::log( logString ); + FM_LOG( logString ); CCoeEnv *env = CCoeEnv::Static(); RFs& fs = env->FsSession(); @@ -277,9 +313,11 @@ int err( fs.UnlockDrive( drive, password, ETrue) ); logString = "Drive:" + QString::number( drive ); - FmLogger::log( logString ); + FM_LOG( logString ); logString = "Unlock drive error:" + QString::number( err ); - FmLogger::log( logString ); + FM_LOG( logString ); + + delete password16; if( err == KErrNone ){ return FmErrNone; @@ -300,25 +338,26 @@ int FmUtils::checkDrivePwd( const QString &driverName, const QString &pwd ) { - if( driverName.isEmpty() ) { + if( driverName.isEmpty() || pwd.length() > FmMaxLengthofDrivePassword ) { return FmErrWrongParam; } QString logString = "checkDrivePwd Drive name:" + driverName; logString += " password:" + pwd; - FmLogger::log( logString ); + FM_LOG( logString ); return setDrivePwd( driverName, pwd, pwd ); } int FmUtils::setDrivePwd( const QString &driverName, const QString &oldPwd, const QString &newPwd) { - if( driverName.isEmpty() ) { + if( driverName.isEmpty() || + oldPwd.length() > FmMaxLengthofDrivePassword || newPwd.length() > FmMaxLengthofDrivePassword ) { return FmErrWrongParam; } QString logString = "setDrivePwd Drive name:" + driverName ; logString += " Old password:" + oldPwd; logString += " New password:" + newPwd; - FmLogger::log( logString ); + FM_LOG( logString ); CCoeEnv *env = CCoeEnv::Static(); RFs& fs = env->FsSession(); @@ -341,10 +380,12 @@ int err( fs.LockDrive( drive, oldPassword, newPassword, ETrue ) ); logString = "Drive:" + QString::number( drive ); - FmLogger::log( logString ); + FM_LOG( logString ); logString = "Password set error:" + QString::number( err ); - FmLogger::log( logString ); + FM_LOG( logString ); + delete newPassword16; + delete oldPassword16; if( err == KErrNone ){ return FmErrNone; } @@ -358,10 +399,10 @@ void FmUtils::emptyPwd( QString &pwd ) { - TPtr des ( ( XQConversions::qStringToS60Desc( pwd ) )->Des() ); - des.FillZ( des.MaxLength() ); - des.Zero(); - pwd = XQConversions::s60DescToQString( des ); + TBuf< FmMaxLengthofDrivePassword > nullPwd; + nullPwd.FillZ( nullPwd.MaxLength() ); + nullPwd.Zero(); + pwd = XQConversions::s60DescToQString( nullPwd ); } int FmUtils::renameDrive( const QString &driverName, const QString &newVolumeName) @@ -391,7 +432,7 @@ int err( fs.SetVolumeLabel( newName, drive )); QString logString = "Rename error:" + QString::number( err ); - FmLogger::log( logString ); + FM_LOG( logString ); if( err == KErrNone ){ return FmErrNone; @@ -410,7 +451,7 @@ return FmErrWrongParam; } QString logString = "FmUtils::ejectDrive start"; - FmLogger::log( logString ); + FM_LOG( logString ); TInt drive = 0; drive = driverName[0].toUpper().toAscii() - 'A' + EDriveA; @@ -456,7 +497,7 @@ RFs fs; err = fs.Connect(); - QString string( formatPath( folderPath ) ); + QString string( fillPathWithSplash( folderPath ) ); TPtrC desFolderPath( XQConversions::qStringToS60Desc( string )->Des() ); TPtrC ptrExtension( XQConversions::qStringToS60Desc( extension )->Des() ); @@ -601,6 +642,11 @@ CleanupStack::PopAndDestroy( array ); } +/*! + fill splash in the end of \a filePath if the path is not a file + All "/" and "\" will be changed to QDir::separator + \sa formatPath only changed "/" and "\" to QDir::separator +*/ QString FmUtils::fillPathWithSplash( const QString &filePath ) { QString newFilePath; @@ -608,18 +654,11 @@ return newFilePath; } - foreach( QChar ch, filePath ) { - if( ch == QChar('\\') || ch == QChar('/') ) { - newFilePath.append( QDir::separator() ); - } else { - newFilePath.append( ch ); - } - } + newFilePath = formatPath( filePath ); if( newFilePath.right( 1 )!= QDir::separator() ){ newFilePath.append( QDir::separator() ); } - return newFilePath; } @@ -667,14 +706,14 @@ { QString logString; logString = QString( "checkFolderToDriveFilter: " ) + path; - FmLogger::log( logString ); + FM_LOG( logString ); QString checkedPath = fillPathWithSplash( path ); logString = QString( "checkFolderToDriveFilter_fillPathWithSplash: " ) + checkedPath; - FmLogger::log( logString ); + FM_LOG( logString ); if( checkedPath.compare( Folder_C_Data, Qt::CaseInsensitive ) == 0 ) { - FmLogger::log( QString( " change from c:/data/ to C:/" ) ); + FM_LOG( QString( " change from c:/data/ to C:/" ) ); return Drive_C; } return path; @@ -684,54 +723,58 @@ int FmUtils::isPathAccessabel( const QString &path ) { // Used to check if path is accessable, very important feature - // and will return filemanager error. - FmLogger::log( QString( "isPathAccessabel:" ) + path ); + // and will return filemanager error. + FM_LOG( QString( "isPathAccessabel:" ) + path ); if( path.isEmpty() ) { return FmErrPathNotExist; } - if( path.length() <= 3 && !isDriveAvailable( path ) ) { //used to filter locked drive - FmLogger::log( QString( "isPathAccessabel false: path is drive and not available" ) ); + + // used to filter locked/ejected/corrupted drive + // check if drive is available, no matter if it is a drive, a folder, or a file. + if( !isDriveAvailable( path ) ) { + FM_LOG( QString( "isPathAccessabel false: path is drive and not available" ) ); return FmErrDriveNotAvailable; } + QFileInfo fileInfo( path ); if( fileInfo.absoluteFilePath().contains( Drive_C, Qt::CaseInsensitive ) && !fileInfo.absoluteFilePath().contains( Folder_C_Data, Qt::CaseInsensitive ) ) { - FmLogger::log( QString( "isPathAccessabel false: path contain C and not in data folder" ) ); + FM_LOG( QString( "isPathAccessabel false: path contain C and not in data folder" ) ); return FmErrPathDenied; } if( !checkDriveAccessFilter( FmUtils::getDriveNameFromPath( fileInfo.absoluteFilePath() ) ) ){ return FmErrDriveDenied; } if( !fileInfo.exists() ) { - FmLogger::log( QString( "isPathAccessabel false: path not exist" ) ); + FM_LOG( QString( "isPathAccessabel false: path not exist" ) ); return FmErrPathNotExist; } - FmLogger::log( QString( "isPathAccessabel FmErrNone" ) ); + FM_LOG( QString( "isPathAccessabel FmErrNone" ) ); return FmErrNone; } // only used to check drive, when MMC is not inserted, also return false bool FmUtils::isDriveAvailable( const QString &path ) { - FmLogger::log( QString( "isDriveAvailable:" ) + path ); + FM_LOG( QString( "isDriveAvailable:" ) + path ); if( path.isEmpty() ) { return false; } FmDriverInfo::DriveState driveState = queryDriverInfo( path ).driveState(); if( ( driveState & FmDriverInfo::EDriveAvailable ) ) { - FmLogger::log( QString( "isDriveAvailable true" ) ); + FM_LOG( QString( "isDriveAvailable true" ) ); return true; } - FmLogger::log( QString( "isDriveAvailable false" ) ); + FM_LOG( QString( "isDriveAvailable false" ) ); return false; } void FmUtils::getDriveList( QStringList &driveList, bool isHideUnAvailableDrive ) { if( isHideUnAvailableDrive ) { - FmLogger::log( QString( "getDriveList HideUnAvailableDrive_true" ) ); + FM_LOG( QString( "getDriveList HideUnAvailableDrive_true" ) ); } else { - FmLogger::log( QString( "getDriveList HideUnAvailableDrive_false" ) ); + FM_LOG( QString( "getDriveList HideUnAvailableDrive_false" ) ); } QFileInfoList infoList = QDir::drives(); @@ -749,6 +792,10 @@ return; } +/*! + fill volume name for \a driveName, with drive letter at the front, for example, C: Phone memory + if \a isFillWithDefaultVolume is true, default volume is provided for non-volume drive. +*/ QString FmUtils::fillDriveVolume( QString driveName, bool isFillWithDefaultVolume ) { QString ret; @@ -761,36 +808,73 @@ FmDriverInfo driverInfo = FmUtils::queryDriverInfo( tempDriveName ); QString volumeName = driverInfo.volumeName(); - + if( volumeName.isEmpty() && isFillWithDefaultVolume ){ - FmDriverInfo::DriveState driveState = queryDriverInfo( tempDriveName ).driveState(); - if( driveState & FmDriverInfo::EDriveAvailable ){ - if( driveState & FmDriverInfo::EDriveRemovable ) { - if( driveState & FmDriverInfo::EDriveMassStorage ) { - // Mass Storage - ret = hbTrId( "txt_fmgr_dblist_1_mass_storage" ).arg( checkedDriveName ); - } else if( driveState & FmDriverInfo::EDriveUsbMemory ) { - // USB Memory - ret = hbTrId( "txt_fmgr_dblist_1_usb_memory" ).arg( checkedDriveName ); - } else{ - // Memory Card - ret = hbTrId( "txt_fmgr_dblist_1_memory_card" ).arg( checkedDriveName ); - } - } else{ - // phone memory + switch ( driverInfo.driveType() ) + { + case FmDriverInfo::EDriveTypeMassStorage: + ret = hbTrId( "txt_fmgr_dblist_1_mass_storage" ).arg( checkedDriveName ); + break; + case FmDriverInfo::EDriveTypeUsbMemory: + ret = hbTrId( "txt_fmgr_dblist_1_usb_memory" ).arg( checkedDriveName ); + break; + case FmDriverInfo::EDriveTypeMemoryCard: + ret = hbTrId( "txt_fmgr_dblist_1_memory_card" ).arg( checkedDriveName ); + break; + case FmDriverInfo::EDriveTypePhoneMemory: ret = hbTrId( "txt_fmgr_dblist_1_device_memory" ).arg( checkedDriveName ); - } - } + break; + default: + Q_ASSERT_X( false, "FmUtils::fillDriveVolume", "please handle drive type"); + break; + } } if( ret.isEmpty() ) { - // set ret as volumeName + // ret is not got. fill ret as default method // txt_fmgr_dblist_1_2 is not correct, can not use. ret = hbTrId( "%1 %2" ).arg( checkedDriveName ).arg( volumeName ); } return ret; } + +/*! + return volume name for \a driveName. without drive letter at the front. + \a defaultName is set true if default volume name is return for volume name +*/ +QString FmUtils::getVolumeNameWithDefaultNameIfNull( const QString &diskName, bool &defaultName ) +{ + FmDriverInfo driverInfo = FmUtils::queryDriverInfo( diskName ); + + QString volumeName = driverInfo.volumeName(); + //save the volume status, whether it is default name + defaultName = false; + //volume name may be null if not set, it will be set at least for one time in the following while cycling. + if ( volumeName.isEmpty() ) { + defaultName = true; + switch ( driverInfo.driveType() ) + { + case FmDriverInfo::EDriveTypeMassStorage: + volumeName = hbTrId("Mass storage"); + break; + case FmDriverInfo::EDriveTypeUsbMemory: + volumeName = hbTrId("USB memory"); + break; + case FmDriverInfo::EDriveTypeMemoryCard: + volumeName = hbTrId("Memory card"); + break; + case FmDriverInfo::EDriveTypePhoneMemory: + volumeName = hbTrId("Device memory"); + break; + default: + Q_ASSERT_X( false, "FmUtils::getVolumeNameWithDefaultNameIfNull", "please handle drive type" ); + break; + } + } + return volumeName; +} + int FmUtils::launchFile( const QString &filePath ) { QFile file( filePath ); @@ -875,7 +959,7 @@ QString FmUtils::Localize( const QString &path ) { - QString locPath = formatPath( path ); + QString locPath = fillPathWithSplash( path ); TPtrC desPath( XQConversions::qStringToS60Desc( locPath )->Des() ); CDirectoryLocalizer *localizer = CDirectoryLocalizer::NewL(); @@ -888,9 +972,17 @@ return QString(); } +/*! + All "/" and "\" in \a path will be changed to QDir::separator + \sa fillPathWithSplash, fillPathWithSplash will append QDir::separator in the end if path is no a file +*/ QString FmUtils::formatPath( const QString &path ) { QString formatPath; + if( path.isEmpty() ) { + return formatPath; + } + foreach( QChar ch, path ) { if( ch == QChar('\\') || ch == QChar('/') ) { formatPath.append( QDir::separator() ); @@ -899,9 +991,6 @@ } } - if( formatPath.right( 1 ) != QDir::separator() ){ - formatPath.append( QDir::separator() ); - } return formatPath; } @@ -917,33 +1006,41 @@ } return true; } + bool FmUtils::checkFolderFileName( const QString& name ) { - if( name.endsWith( QChar('.'), Qt::CaseInsensitive ) ) { + // trim space firest, because there may be some spaces after "." , it is also not valid + QString trimmedName( name.trimmed() ); + if( trimmedName.isEmpty() ) { + return false; + } + if( trimmedName.endsWith( QChar('.'), Qt::CaseInsensitive ) ) { return false; } - if( name.contains( QChar('\\'), Qt::CaseInsensitive ) || - name.contains( QChar('/'), Qt::CaseInsensitive ) || - name.contains( QChar(':'), Qt::CaseInsensitive ) || - name.contains( QChar('*'), Qt::CaseInsensitive ) || - name.contains( QChar('?'), Qt::CaseInsensitive ) || - name.contains( QChar('\"'), Qt::CaseInsensitive ) || - name.contains( QChar('<'), Qt::CaseInsensitive ) || - name.contains( QChar('>'), Qt::CaseInsensitive ) || - name.contains( QChar('|'), Qt::CaseInsensitive ) ){ + if( trimmedName.contains( QChar('\\'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('/'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar(':'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('*'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('?'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('\"'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('<'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('>'), Qt::CaseInsensitive ) || + trimmedName.contains( QChar('|'), Qt::CaseInsensitive ) ){ return false; } + // use orignal name to exam max size of file name if( name.length() > KMaxFileName ) { return false; } return true; } -bool FmUtils::checkNewFolderOrFile( const QString &path, QString &errString ) +bool FmUtils::checkNewFolderOrFile( const QString &fileName, const QString &path, QString &errString ) { + // first check if fileName is valid, then check if path length is valid, and check if file/foler is existed at last QFileInfo fileInfo( path ); bool ret( true ); - if (!FmUtils::checkFolderFileName( fileInfo.fileName() ) ) { + if (!FmUtils::checkFolderFileName( fileName ) ) { errString = hbTrId( "Invalid file or folder name!" ); ret = false; } else if( !FmUtils::checkMaxPathLength( path ) ) { @@ -955,3 +1052,62 @@ } return ret; } + +/*! + Check if \a dest is sub level path of \a src + Used to check True/False when copy a folder to itself or its subfolder + For example, c:\data\test is sub path of c:\data. + But c:\data123\test is not sub path of c:\data. + So after got right part of path, the first char must be \ or / +*/ +bool FmUtils::isSubLevelPath( const QString &src, const QString &dest ) +{ + FM_LOG("FmUtils::isSubFolder: src=" + src + " dest=" + dest); + QString checkedSrc( FmUtils::fillPathWithSplash( src ) ); + QString checkedDest( FmUtils::fillPathWithSplash( dest ) ); + + if( checkedDest.contains( checkedSrc, Qt::CaseInsensitive) && + checkedDest.length() > checkedSrc.length() ) { + // for example c:\data\ vs c:\data\123\ + FM_LOG("FmUtils::isSubFolder: true"); + return true; + } + // for example c:\data\ vs c:\data\ + // for example c:\data\ vs c:\data123\ + + FM_LOG("FmUtils::isSubFolder: false"); + return false; +} + +/*! + set the \a desFile attributes as the same with \a srcFile +*/ +int FmUtils::setFileAttributes( const QString &srcFile, const QString &desFile ) +{ + RFs fsSession; + User::LeaveIfError( fsSession.Connect() ); + CleanupClosePushL( fsSession ); + RFile64 src; + RFile64 des; + HBufC *buf1 = XQConversions::qStringToS60Desc( removePathSplash( formatPath( srcFile ) ) ); + HBufC *buf2 = XQConversions::qStringToS60Desc( removePathSplash( formatPath( desFile ) ) ); + User::LeaveIfError( src.Open( fsSession, *buf1, EFileRead | EFileShareReadersOnly ) ); + User::LeaveIfError( des.Open( fsSession, *buf2, EFileWrite | EFileShareExclusive ) ); + TTime mod; + int err = src.Modified( mod );; + if ( err == FmErrNone ) { + err = des.SetModified( mod ); + } + TUint att( 0 ); + if ( err == FmErrNone ) { + err = src.Att( att ); + } + if ( err == FmErrNone ) { + des.SetAtt( att, ( ~att ) & KEntryAttMaskSupported ); + } + src.Close(); + des.Close(); + fsSession.Close(); + CleanupStack::PopAndDestroy(); // fsSession + return err; +}