--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitymodules/SeCon/services/ftp/src/sconftp.cpp Wed Sep 01 12:20:56 2010 +0100
@@ -0,0 +1,1588 @@
+/*
+* Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: File Transfer Controller implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <pathinfo.h>
+#include <stringresourcereader.h>
+#include <bautils.h>
+#include <driveinfo.h>
+#include <sconftp.rsg>
+#include <centralrepository.h>
+#include <sysutildomaincrkeys.h>
+
+#include "debug.h"
+#include "sconftp.h"
+#include "sconfshandler.h"
+#include "sconinboxhandler.h"
+#include "sconconsts.h"
+
+const TInt KPackageSize = 65536;
+
+// ============================= MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CreateCSConFTPL()
+// Entry to CSConFTP
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSConFTP* CreateCSConFTPL()
+ {
+ TRACE_FUNC;
+ return CSConFTP::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::NewL()
+// Two-phase constructor
+// -----------------------------------------------------------------------------
+//
+CSConFTP* CSConFTP::NewL()
+ {
+ TRACE_FUNC_ENTRY;
+ CSConFTP* self = new (ELeave) CSConFTP();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ TRACE_FUNC_EXIT;
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::~CSConFTP()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CSConFTP::~CSConFTP()
+ {
+ TRACE_FUNC_ENTRY;
+ delete iSConInboxHandler;
+ iSConInboxHandler = NULL;
+ delete iSConFsHandler;
+ iSConFsHandler = NULL;
+ delete iBuffer;
+ iBuffer = NULL;
+
+ iFs.Delete( iTempFileName );
+ iFs.Close();
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::GetFolderObjectL( CObexBufObject*& aObjectList )
+// Gets object that contains folder listing from inbox or file system
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::GetFolderObjectL( CObexBufObject*& aObjectList )
+ {
+ TRACE_FUNC_ENTRY;
+
+ TInt ret( KErrNone );
+ TInt offset = 0;
+ TChar driveLetter;
+ TBuf8<KSConDriveNameLength> tmpBuf8;
+
+ iBuffer->Reset();
+
+ //default folder list - lists all available drives, inbox
+ if( iPathName.Length() == 0 )
+ {
+ TInt devDriveCount = 0;
+ TInt mmcDriveCount = 0;
+
+ iBuffer->ResizeL( KSConXmlDocBegin().Length() );
+ iBuffer->Write( offset, KSConXmlDocBegin );
+ offset += KSConXmlDocBegin().Length();
+
+ //Write all drivers to folderlisting object
+ TDriveList driveList;
+ // Get all drives that are visible to the user.
+ TInt driveCount;
+ User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) );
+
+ for( TInt i = EDriveA; i < KMaxDrives; i++ )
+ {
+ if( driveList[i] )
+ {
+ TUint driveStatus;
+ User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, i, driveStatus ) );
+ LOGGER_WRITE_1( "DriveInfo for drive: %d", i);
+
+ if( !(driveStatus & DriveInfo::EDrivePresent )
+ || driveStatus & DriveInfo::EDriveCorrupt
+ || (driveStatus & DriveInfo::EDriveRemote) )
+ {
+ LOGGER_WRITE_1( "skip drive %d", i);
+ continue;
+ }
+
+ User::LeaveIfError( iFs.DriveToChar( i, driveLetter ) );
+
+ //Letter to uppercase form.
+ driveLetter.UpperCase();
+
+ //Folder begin
+ iBuffer->ExpandL( offset,
+ KSConXmlFolderNameBegin().Length() );
+ iBuffer->Write( offset, KSConXmlFolderNameBegin );
+ offset += KSConXmlFolderNameBegin().Length();
+
+ iBuffer->ExpandL( offset, KSConDriveCName().Length() );
+
+ tmpBuf8.Delete( 0, tmpBuf8.Length() );
+ tmpBuf8.Append( driveLetter );
+ tmpBuf8.Append( KDriveDelimiter );
+
+ iBuffer->Write( offset, tmpBuf8 );
+ offset += KSConDriveNameLength;
+
+ //permission
+ iBuffer->ExpandL( offset,
+ KSConXmlUserAttributes().Length() );
+ iBuffer->Write( offset, KSConXmlUserAttributes );
+ offset += KSConXmlUserAttributes().Length();
+ if( driveStatus & DriveInfo::EDriveInternal && devDriveCount==0 )
+ {
+ //permission always R for first internal drive
+ iBuffer->ExpandL( offset,
+ KSConXmlUserEntryReadOnly().Length() );
+ iBuffer->Write( offset, KSConXmlUserEntryReadOnly );
+ offset += KSConXmlUserEntryReadOnly().Length();
+ }
+ else
+ {
+ //permission always RW
+ iBuffer->ExpandL( offset,
+ KSConXmlUserEntryDrive().Length() );
+ iBuffer->Write( offset, KSConXmlUserEntryDrive );
+ offset += KSConXmlUserEntryDrive().Length();
+ }
+
+ //memory type
+ iBuffer->ExpandL( offset,
+ KSConXmlMemoryType().Length() );
+ iBuffer->Write( offset, KSConXmlMemoryType );
+ offset += KSConXmlMemoryType().Length();
+ if( driveStatus & DriveInfo::EDriveInternal )
+ {
+ LOGGER_WRITE( "DriveInfo::EDriveInternal" );
+ // DEV type
+ devDriveCount++;
+ if( devDriveCount > 1 )
+ {
+ // DEV2
+ TBuf8<KSConMemTypeMaxLength> memType;
+ memType.Copy( KSConMemoryTypeDev );
+ memType.AppendNum(devDriveCount);
+ iBuffer->ExpandL( offset, memType.Length() );
+ iBuffer->Write( offset, memType );
+ offset += memType.Length();
+ }
+ else
+ {
+ // DEV
+ iBuffer->ExpandL( offset,
+ KSConMemoryTypeDev().Length() );
+ iBuffer->Write( offset, KSConMemoryTypeDev );
+ offset += KSConMemoryTypeDev().Length();
+ }
+ }
+ if( driveStatus & DriveInfo::EDriveRemovable )
+ {
+ LOGGER_WRITE( "DriveInfo::EDriveRemovable" );
+ // MMC type
+ mmcDriveCount++;
+ if( mmcDriveCount > 1 )
+ {
+ // MMC2
+ TBuf8<KSConMemTypeMaxLength> memType;
+ memType.Copy( KSConMemoryTypeMmc );
+ memType.AppendNum(mmcDriveCount);
+ iBuffer->ExpandL( offset, memType.Length() );
+ iBuffer->Write( offset, memType );
+ offset += memType.Length();
+ }
+ else
+ {
+ // MMC
+ iBuffer->ExpandL( offset,
+ KSConMemoryTypeMmc().Length() );
+ iBuffer->Write( offset, KSConMemoryTypeMmc );
+ offset += KSConMemoryTypeMmc().Length();
+ }
+ }
+
+ //memory label
+ iBuffer->ExpandL( offset,
+ KSConXmlMemoryLabel().Length() );
+ iBuffer->Write( offset, KSConXmlMemoryLabel );
+ offset += KSConXmlMemoryLabel().Length();
+
+ TInt err( KErrNotFound );
+ TBuf8<KMaxFileName> volumeName;
+ if( driveStatus & DriveInfo::EDriveRemovable || devDriveCount == 1 )
+ {
+ // get Volume name for C-drive(Phone) and E-drive(MMC)
+ err = GetVolumeNameL( i, volumeName );
+ }
+ else
+ {
+ // Get localized name for DEV2 (Mass memory)
+ //Read memory string and convert it
+ TFileName file( KSConResourceName );
+
+ BaflUtils::NearestLanguageFile( iFs, file );
+
+ CStringResourceReader* reader = CStringResourceReader::NewL( file );
+
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( volumeName,
+ reader->ReadResourceString( R_SECON_VALUE_MASS_STORAGE ) );
+
+ delete reader;
+ err = KErrNone;
+ }
+
+ if ( err == KErrNone )
+ {
+ iBuffer->ExpandL( offset,
+ volumeName.Length() );
+ iBuffer->Write( offset, volumeName );
+ offset += volumeName.Length();
+ }
+
+ //Write the end of filelist to folderlisting object
+ iBuffer->ExpandL( offset, KSConXmlFileEnd().Length() );
+ iBuffer->Write( offset, KSConXmlFileEnd );
+ offset += KSConXmlFileEnd().Length();
+ }
+ }
+ //Write the end of folderlist to folderlisting object
+ iBuffer->ExpandL( offset, KSConXmlFolderListEnd().Length() );
+ iBuffer->Write( offset, KSConXmlFolderListEnd );
+ iBuffer->Compress();
+ }
+ else
+ {
+ if( IsCurrentVolumeOK() )
+ {
+ ret = iSConFsHandler->ParseFolderListL( iBuffer, iPathName, iCurrentDriveTypeNumber );
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+ }
+
+ //Put data to aObjectList
+ delete aObjectList;
+ aObjectList = NULL;
+
+ aObjectList = CObexBufObject::NewL( iBuffer );
+ aObjectList->SetTypeL( KSConFolderListType );
+ aObjectList->SetLengthL( iBuffer->Size() );
+
+ LOGGER_WRITE_1( "CSConFTP::GetFolderObjectL( CObexBufObject*& aObjectList ) : returned %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::GetFileObjectL( CObexFileObject*& aFileObject )
+// Gets object that contains a file from file system
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::GetFileObjectL( CObexFileObject*& aFileObject )
+ {
+ TRACE_FUNC_ENTRY;
+
+ TInt ret( KErrNone );
+
+ if( aFileObject->Name().Length() == 0 )
+ {
+ return KErrBadName;
+ }
+
+ // check is current drive ok
+ if( iPathName.Length() > 0 )
+ {
+ TPath path( KSConAllowedPath );
+ path.Append( KPathDelimiter );
+ if( iPathName.CompareF( path ) != 0 )
+ {
+ // was normal path (not KSConAllowedPath)
+ if( !IsCurrentVolumeOK() )
+ {
+ return KErrNotFound;
+ }
+ }
+ }
+
+ HBufC* nameBuf = HBufC::NewLC( KMaxFileName );
+ TPtr namePtr = nameBuf->Des();
+ namePtr.Append( aFileObject->Name() );
+
+ if( namePtr.LocateReverse( KPathDelimiter ) == namePtr.Length()-1 )
+ {
+ namePtr.Delete( namePtr.Length()-1, 1 );
+ }
+
+ ret = iSConFsHandler->GetFileObjectL( aFileObject, iPathName, namePtr );
+
+ CleanupStack::PopAndDestroy( nameBuf );
+
+ LOGGER_WRITE_1( "CSConFTP::GetFileObjectL() : returned %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::PutFileObjectInitL( CObexBufObject*& aObject,
+// CBufFlat*& aBuffer )
+// Initializes the receiving from the client.
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::PutFileObjectInitL( CObexBufObject*& aObject,
+ CBufFlat*& aBuffer )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt ret( KErrNone );
+
+ RFile file;
+
+ TBool lowMemory = IsCurrentDiskSpaceBelowCritical();
+
+ //if Inbox then save temp file to default drive
+ if( iPathName.Length() == 0 )
+ {
+ //When proprietary profile (PC Suite), doesn't allow to use Inbox
+ if( iProfile == EProprietary )
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectInitL() : iProfile EProprietary" );
+ ret = file.Temp( iFs, PathInfo::PhoneMemoryRootPath(), iTempFileName,
+ EFileWrite | EFileShareExclusive );
+ file.Close();
+
+ if( ret == KErrNone )
+ {
+ CreateObexBufObjectL( aObject, aBuffer );
+ }
+ }
+ else
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectInitL() : not EProprietary" );
+ if( lowMemory )
+ {
+ // do not even try to save
+ LOGGER_WRITE( "CSConFTP::PutFileObjectInitL() : disk full" );
+ ret = KErrNoMemory;
+ }
+ else
+ {
+ ret = iSConInboxHandler->CreateInboxAttachmentL( aObject, aBuffer );
+ }
+ }
+
+ return ret;
+ }
+ else
+ {
+ LOGGER_WRITE_1("iPathName: %S", &iPathName);
+ // check is current drive ok
+ if( !IsCurrentVolumeOK() )
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectInitL() : drive not visible" );
+ ret = KErrNotFound;
+ }
+ else
+ {
+ ret = file.Temp( iFs, iPathName, iTempFileName, EFileWrite |
+ EFileShareExclusive );
+ }
+ }
+
+ file.Close();
+
+ if( ret == KErrNone )
+ {
+ CreateObexBufObjectL( aObject, aBuffer );
+
+ if( lowMemory )
+ {
+ // return error. it's up to pccon/ftp plugin howto handle it..
+ LOGGER_WRITE( "CSConFTP::PutFileObjectInitL() : low memory" );
+ ret = KErrNoMemory;
+ }
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::PutFileObjectInitL( CObexBufObject*& aObject, CBufFlat*& aBuffer ) : returned %d", ret );
+ return ret;
+ }
+
+void CSConFTP::CreateObexBufObjectL( CObexBufObject*& aObject, CBufFlat*& aBuffer )
+ {
+ delete aObject;
+ aObject = NULL;
+ aObject = CObexBufObject::NewL( NULL );
+
+ delete aBuffer;
+ aBuffer = NULL;
+
+ aBuffer = CBufFlat::NewL( KSConBufferSize );
+ aBuffer->ResizeL( KSConBufferSize );
+
+ TObexFilenameBackedBuffer bufferdetails( *aBuffer, iTempFileName,
+ CObexBufObject::EDoubleBuffering );
+ TRAPD( err, aObject->SetDataBufL( bufferdetails ));
+ if ( err == KErrNoMemory )
+ {
+ LOGGER_WRITE( "KErrNoMemory, Using singe buffer strategy");
+ // If fails, use singe buffer strategy to save RAM
+ TObexFilenameBackedBuffer lowMemBufferdetails( *aBuffer, iTempFileName,
+ CObexBufObject::ESingleBuffering );
+ aObject->SetDataBufL( lowMemBufferdetails );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::PutFileObjectFinalizeL( CObexBufObject*& aObject )
+// Stores the relayed file object to inbox or file system.
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::PutFileObjectFinalizeL( CObexBufObject*& aObject )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt ret( KErrNone );
+
+ // if iPathName is not defined trying to save to inbox, no need to call IsCurrentVolumeOK()
+ if( iPathName.Length() > 0 && !IsCurrentVolumeOK() )
+ {
+ // Memory card removed
+ LOGGER_WRITE( "CSConFTP::PutFileObjectFinalizeL() : disk err, return KErrNotFound" );
+ return KErrNotFound;
+ }
+ else if ( iPathName.Length() + aObject->Name().Length() > KMaxFileName )
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectFinalizeL() : Too long filename, return KErrBadName");
+ return KErrBadName;
+ }
+
+ TBool lowMemory = IsCurrentDiskSpaceBelowCritical();
+ if ( lowMemory )
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectFinalizeL() : Low memory, return KErrNoMemory");
+ return KErrNoMemory;
+ }
+
+ HBufC* fullPathBuf = HBufC::NewLC( KMaxFileName );
+ TPtr fullPathPtr = fullPathBuf->Des();
+ fullPathPtr.Copy( iPathName );
+ fullPathPtr.Append( aObject->Name() );
+
+ // Save to inbox if path is not set.
+ if( iPathName.Length() == 0 )
+ {
+ LOGGER_WRITE( "CSConFTP::PutFileObjectFinalizeL before SaveObjectToInbox" );
+ ret = iSConInboxHandler->SaveObjToInboxL( aObject );
+ LOGGER_WRITE_1( "CSConFTP::PutFileObjectFinalize SaveObjectToInbox returned %d", ret );
+ }
+ else if( iPathName.CompareF( K_C_ROOT ) == 0 )
+ {
+ // Saving to root of C:\ is not allowed
+ ret = KErrAccessDenied;
+ }
+ //Save to file system
+ else
+ {
+ TTime time = aObject->Time();
+
+ // UTC offset
+ time -= User::UTCOffset();
+
+ delete aObject;
+ aObject = NULL;
+
+ ret = iSConFsHandler->SaveFileObjectL( fullPathPtr, time,
+ iTempFileName );
+ }
+
+ CleanupStack::PopAndDestroy( fullPathBuf );
+
+ LOGGER_WRITE_1( "CSConFTP::PutFileObjectFinalizeL( CObexBufObject*& aObject ) : returned %d", ret );
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetPathL( const TPtrC aPath, const TUint8 aFlags )
+// Changes the current path. The path can point to inbox or file system
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::SetPathL( const TPtrC aPath, const TUint8 aFlags )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1( "aPath: %S", &aPath );
+ TInt ret( KErrNone );
+
+ if( ( aPath.Length() > 0 && aFlags != KSConSetPathRoot )
+ || ( iPathName.Length() == KDriveLength && aFlags == KSConSetPathBack) )
+ {
+ // check is current drive ok
+ if( !IsCurrentVolumeOK() )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathL() : drive not found" );
+ return KErrNotFound;
+ }
+ }
+
+ ret = KErrNotFound;
+
+ //path forward, deny access to forbidden directories and drives
+ if( aPath.Length() > 0
+ && ( iPathName.Length() + aPath.Length() < KMaxFileName )
+ && ( aFlags == KSConSetPathForward || aFlags == KSConSetPathDontCreate ) )
+ {
+ ret = SetPathForwardL( aPath, aFlags );
+ }
+ //path backward
+ else if( aFlags == KSConSetPathBack )
+ {
+ ret = SetPathBackwardL( aPath );
+ }
+ //path root
+ else if( aPath.Length() == 0 && aFlags == KSConSetPathRoot )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathL() : KSConSetPathRoot" );
+ if( iPathName.Length() > 0 )
+ {
+ iPathName.Delete( 0, iPathName.Length() );
+ }
+ iCurrentDrive = KErrNotFound;
+ ret = KErrNone;
+ }
+
+ if( ret == KErrNone )
+ {
+ // drive may have changed, update info
+ UpdateDriveTypeInfoL();
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::CSConFTP::SetPathL( const TPtrC aPath, const TUint8 aFlags ) : returned %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetPathForwardL( const TPtrC aPath, const TUint8 aFlags )
+// Set path forward
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::SetPathForwardL( const TPtrC aPath, const TUint8 aFlags )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt ret(KErrNone);
+ HBufC* fullPath = HBufC::NewLC( KMaxFileName );
+ TPtr fullPathPtr = fullPath->Des();
+
+ if( iPathName.Length() == 0 )
+ {
+ fullPathPtr.Copy( aPath );
+ }
+ else
+ {
+ fullPathPtr.Copy( iPathName );
+ fullPathPtr.Append( aPath );
+ }
+ LOGGER_WRITE_1( "fullPathPtr: %S", &fullPathPtr );
+ // now fullpath is new path
+ // check validity
+ if( fullPathPtr.Length() < 2 || fullPathPtr[1] != KDriveDelimiter )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathForwardL() : not valid name" );
+ CleanupStack::PopAndDestroy( fullPath );
+ return KErrNotFound;
+ }
+
+ if( fullPathPtr.CompareF( KSConAllowedPath ) == 0 )
+ {
+ // Always access to PC Suite configuration file on ROM
+ LOGGER_WRITE( "CSConFTP::SetPathForwardL() : KSConAllowedPath" );
+ iPathName.Copy( fullPathPtr );
+ if( iPathName[iPathName.Length()-1] != KPathDelimiter )
+ {
+ iPathName.Append( KPathDelimiter );
+ }
+
+ CleanupStack::PopAndDestroy( fullPath );
+ return KErrNone;
+ }
+
+ // check drive
+ TInt driveNumber;
+ TInt err = iFs.CharToDrive( fullPathPtr[0], driveNumber );
+ if( err != KErrNone || !IsDriveVisible( driveNumber ) )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathForwardL() : drive err" );
+ CleanupStack::PopAndDestroy( fullPath );
+ return KErrNotFound;
+ }
+
+ // check folder and create it if needed
+ if( fullPathPtr.Length() > 2 )
+ {
+ TBool isFolder = EFalse;
+ err = BaflUtils::IsFolder( iFs, fullPathPtr, isFolder );
+ if( err != KErrNone )
+ {
+ isFolder = EFalse;
+ }
+ LOGGER_WRITE_1( "CSConFTP::SetPathForwardL() IsFolder: %d", (TInt)isFolder );
+
+ if( !isFolder )
+ {
+ //if "Don't create" is 1
+ if( aFlags & 2 )
+ {
+ ret = KErrNotFound;
+ }
+ else
+ {
+ CreateFolderL( fullPathPtr );
+ ret = KErrNone;
+ }
+ }
+ else
+ {
+ ret = KErrNone;
+ }
+ }
+ else
+ {
+ ret = KErrNone;
+ }
+
+ if( ret == KErrNone )
+ {
+ iPathName.Copy( fullPathPtr );
+
+ if( iPathName[iPathName.Length()-1] != KPathDelimiter )
+ {
+ iPathName.Append( KPathDelimiter );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( fullPath );
+ LOGGER_WRITE_1( "CSConFTP::SetPathForwardL() : end, ret: %d", ret );
+ return ret;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetPathBackwardL( const TPtrC aPath )
+// Set path backward
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::SetPathBackwardL( const TPtrC aPath )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt ret(KErrNotFound);
+ if( iPathName.Length() == 0 )
+ {
+ // already in root, exit
+ LOGGER_WRITE( "CSConFTP::SetPathBackwardL() : already in root" );
+ LOGGER_WRITE_1( "CSConFTP::SetPathBackwardL() : end, ret: %d", ret );
+ return ret;
+ }
+ TInt pos;
+ TBool isFolder(EFalse);
+ HBufC* fullPath = HBufC::NewLC( KMaxFileName );
+ TPtr fullPathPtr = fullPath->Des();
+
+ //no directory/folder name
+ if( aPath.Length() == 0 )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathBackwardL() : no new path, goto parent" );
+ iPathName.Delete( iPathName.Length()-1, 1 );
+ pos = iPathName.LocateReverse( KPathDelimiter );
+ iPathName.Delete( pos+1, iPathName.Length()-pos );
+ ret = KErrNone;
+ }
+ //if folder name
+ else if( aPath.Locate( KDriveDelimiter ) != 1 && iPathName.Length() > KDriveLength )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathBackwardL() : goto parent and new path" );
+ fullPathPtr.Copy( iPathName );
+ fullPathPtr.Delete( fullPathPtr.Length()-1, 1 );
+ pos = fullPathPtr.LocateReverse( KPathDelimiter );
+ fullPathPtr.Delete( pos+1, fullPathPtr.Length()-pos );
+ fullPathPtr.Append( aPath );
+
+ if( fullPathPtr.CompareF( KSConAllowedPath ) == 0 )
+ {
+ // Always access to PC Suite configuration file on ROM
+ isFolder = ETrue;
+ }
+ else
+ {
+ TInt driveNumber;
+ TInt err = iFs.CharToDrive(fullPathPtr[0], driveNumber);
+ if( err != KErrNone )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathForwardL() : drive err" );
+ isFolder = EFalse;
+ }
+ else if( !IsDriveVisible(driveNumber) )
+ {
+ isFolder = EFalse;
+ }
+ else
+ {
+ // drive ok, check folder.
+ err = BaflUtils::IsFolder( iFs, fullPathPtr, isFolder );
+ if( err != KErrNone )
+ {
+ isFolder = EFalse;
+ }
+ }
+ }
+
+ if( isFolder )
+ {
+ iPathName.Copy( fullPathPtr );
+
+ if( aPath.LocateReverse( KPathDelimiter ) != aPath.Length()-1 )
+ {
+ iPathName.Append( KPathDelimiter );
+ }
+
+ ret = KErrNone;
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+
+ }
+ //drive
+ else if( aPath.Locate( KDriveDelimiter ) == 1 )
+ {
+ fullPathPtr.Copy( aPath );
+ if( fullPathPtr.LocateReverse( KPathDelimiter )
+ != fullPathPtr.Length()-1 )
+ {
+ fullPathPtr.Append( KPathDelimiter );
+ }
+
+ TFileName tempPath( KSConAllowedPath );
+ tempPath.Append(KPathDelimiter);
+ if( fullPathPtr.CompareF( tempPath ) == 0 )
+ {
+ // Always access to PC Suite configuration file on ROM
+ isFolder = ETrue;
+ }
+ else
+ {
+ TInt driveNumber;
+ TInt err = iFs.CharToDrive(fullPathPtr[0], driveNumber);
+ if( err != KErrNone )
+ {
+ LOGGER_WRITE( "CSConFTP::SetPathForwardL() : drive err" );
+ isFolder = EFalse;
+ }
+ else if( !IsDriveVisible(driveNumber) )
+ {
+ isFolder = EFalse;
+ }
+ else
+ {
+ // drive ok, check folder.
+ err = BaflUtils::IsFolder( iFs, fullPathPtr, isFolder );
+ if( err != KErrNone )
+ {
+ isFolder = EFalse;
+ }
+ }
+ }
+
+ if( isFolder )
+ {
+ iPathName.Copy( fullPathPtr );
+
+ if( aPath.LocateReverse( KPathDelimiter ) != aPath.Length()-1 )
+ {
+ iPathName.Append( KPathDelimiter );
+ }
+
+ ret = KErrNone;
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+ }
+ CleanupStack::PopAndDestroy( fullPath );
+ LOGGER_WRITE_1( "CSConFTP::SetPathBackwardL() : end, ret: %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::CreateFolderL( const TPtrC aFolderName )
+// Creates a new folder to file system
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::CreateFolderL( const TPtrC aFolderName )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1( "aFolderName: %S", &aFolderName );
+ TInt ret( KErrNone );
+ if( aFolderName.Length() == 0 )
+ {
+ return KErrArgument;
+ }
+
+ HBufC* pathBuf = HBufC::NewLC( KMaxFileName );
+ TPtr pathBufPtr = pathBuf->Des();
+ //absolute folder path
+ if( aFolderName.Length() > 1 && aFolderName[1] == KDriveDelimiter )
+ {
+ if ( iPathName.Length()>0 )
+ {
+ LOGGER_WRITE( "CSConFTP::CreateFolderL() : KErrBadName" );
+ CleanupStack::PopAndDestroy( pathBuf );
+ return KErrBadName;
+ }
+ pathBufPtr.Copy( aFolderName );
+ }
+ else
+ {
+ pathBufPtr.Copy( iPathName );
+ pathBufPtr.Append( aFolderName );
+ }
+
+ if( !iFs.IsValidName( pathBufPtr ) )
+ {
+ ret = KErrBadName;
+ }
+ else
+ {
+ // check drive
+ TInt driveNumber;
+ ret = iFs.CharToDrive(pathBufPtr[0], driveNumber);
+ if( ret != KErrNone || !IsDriveVisible(driveNumber) )
+ {
+ LOGGER_WRITE( "CSConFTP::CreateFolderL() : drive err" );
+ ret = KErrNotFound;
+ }
+ }
+
+ if ( ret == KErrNone )
+ {
+ if( pathBufPtr.LocateReverse( KPathDelimiter ) != pathBufPtr.Length()-1 )
+ {
+ pathBufPtr.Append( KPathDelimiter );
+ }
+ ret = iSConFsHandler->CreateFolderL( pathBufPtr );
+ }
+
+ if( ret == KErrNone || ret == KErrAlreadyExists )
+ {
+ ret = SetPathL( aFolderName, KSConSetPathForward );
+ }
+
+ CleanupStack::PopAndDestroy( pathBuf );
+
+ LOGGER_WRITE_1( "CSConFTP::CreateFolderL( const TPtrC aFolderName ) : returned %d", ret );
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::DeleteObjectL( const TPtrC aObjectName )
+// Deletes file/folder from inbox or file system
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::DeleteObjectL( const TPtrC aObjectName )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1( "aObjectName: %S", &aObjectName );
+ TInt ret( KErrNone );
+ TFileName tmpTarget;
+ HBufC* targetBuf = HBufC::NewLC( KMaxFileName );
+ TPtr target = targetBuf->Des();
+
+ //absolute folder path
+ if( aObjectName.Length() > 1 && aObjectName[1] == KDriveDelimiter )
+ {
+ if ( iPathName.Length()>0 )
+ {
+ LOGGER_WRITE( "CSConFTP::DeleteObjectL() : KErrBadName" );
+ CleanupStack::PopAndDestroy( targetBuf );
+ return KErrBadName;
+ }
+ target.Copy( aObjectName );
+ }
+ else
+ {
+ target.Copy( iPathName );
+ target.Append( aObjectName );
+ }
+
+ if( !iFs.IsValidName( target ) )
+ {
+ ret = KErrBadName;
+ }
+ else
+ {
+ TInt driveNumber;
+ ret = iFs.CharToDrive(target[0], driveNumber);
+ if( ret != KErrNone || !IsDriveVisible(driveNumber) )
+ {
+ LOGGER_WRITE( "CSConFTP::DeleteObjectL() : drive err" );
+ ret = KErrNotFound;
+ }
+ }
+
+
+ if ( ret == KErrNone )
+ {
+ ret = iSConFsHandler->DeleteObjectL( target );
+ }
+
+ CleanupStack::PopAndDestroy( targetBuf );
+
+ LOGGER_WRITE_1( "CSConFTP::DeleteObjectL( const TPtrC aObjectName ) : returned %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::GetPath( TDes& aPath )
+// Gets the current path
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::GetPath( TDes& aPath )
+ {
+ TRACE_FUNC;
+ aPath.Copy( iPathName );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::AbortFileTransfer( CObexBufObject*& aObject )
+// Abort file transfer
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::AbortFileTransfer( CObexBufObject*& aObject )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt err( KErrNone );
+
+ if( iPathName.Length() == 0 )
+ {
+ iSConInboxHandler->AbortInboxOperation( aObject );
+ }
+
+ //aObject has to be deleted, otherwise the temp file is locked
+ delete aObject;
+ aObject = NULL;
+
+ err = iFs.Delete( iTempFileName );
+
+ LOGGER_WRITE_1( "CSConFTP::AbortFileTransfer( CObexBufObject*& aObject ) : iFs.Delete() err: %d", err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetProfile( TInt aProfile )
+// Set used transfer profile
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::SetProfile( TSConProfile aProfile )
+ {
+ TRACE_FUNC;
+ iProfile = aProfile;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetBackupStarted( TBool aValue )
+// Set backup status
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::SetBackupStarted( TBool aValue )
+ {
+ TRACE_FUNC;
+ iBackupStarted = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetUsedMedia( TSConUsedMedia aMedia )
+// Set the used media information
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::SetUsedMedia( TSConUsedMedia aMedia )
+ {
+ TRACE_FUNC;
+ iMedia = aMedia;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::IsCurrentDiskSpaceBelowCritical( TUint32 aFilesize )
+// Check is current disk space below critical level.
+// -----------------------------------------------------------------------------
+//
+TBool CSConFTP::IsCurrentDiskSpaceBelowCritical( TUint32 aFilesize )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1( "aFilesize: %d", aFilesize );
+ TInt drive;
+ TInt err;
+
+ if( iCurrentDrive != KErrNotFound )
+ {
+ drive = iCurrentDrive;
+ }
+ else
+ {
+ LOGGER_WRITE( "CSConFTP::IsCurrentDiskSpaceBelowCritical() : drive not specified, use default drive" );
+ err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, drive );
+ if( err )
+ {
+ LOGGER_WRITE_1( "CSConFTP::IsCurrentDiskSpaceBelowCriticaL() : DriveInfo::GetDefaultDrive err %d", err );
+ return ETrue; //exit
+ }
+ }
+
+ // check disk space
+ LOGGER_WRITE_1( "drive: %d", drive );
+ TVolumeInfo volumeInfo;
+ err = iFs.Volume(volumeInfo, drive);
+ if( err != KErrNone )
+ {
+ LOGGER_WRITE_1( "CSConFTP::IsCurrentDiskSpaceBelowCritical() : iFs.Volume err %d", err );
+ LOGGER_WRITE( "CSConFTP::IsCurrentDiskSpaceBelowCritical() : End" );
+ return ETrue; //exit
+ }
+ LOGGER_WRITE_1( "volumeInfo.iFree: %Ld", volumeInfo.iFree );
+ TBool diskLevelCritical( EFalse );
+ if ( volumeInfo.iFree - aFilesize <= iCriticalDiskLevel )
+ {
+ // Can not write the data, there's not enough free space on disk.
+ diskLevelCritical = ETrue;
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::IsCurrentDiskSpaceBelowCritical() : ret %d",
+ (TInt)diskLevelCritical );
+ return diskLevelCritical;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::ReadWBXMLDataL( CBufFlat*& aBuffer )
+// Read received ConML protocol packet
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::ReadWBXMLDataL( CBufFlat*& aBuffer )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt ret( KErrNone );
+
+ RFile file;
+ TInt fileSize;
+
+ ret = file.Open( iFs, iTempFileName, EFileRead|EFileShareAny );
+ CleanupClosePushL( file );
+ if( ret == KErrNone )
+ {
+ file.Size( fileSize );
+
+ delete aBuffer;
+ aBuffer = NULL;
+
+ HBufC8* wbxmlDataBuf = HBufC8::NewLC( fileSize );
+ TPtr8 wbxmlDataPtr = wbxmlDataBuf->Des();
+
+ file.Read( wbxmlDataPtr );
+
+ aBuffer = CBufFlat::NewL( KSConBufSize );
+ aBuffer->ExpandL( 0, fileSize );
+ aBuffer->Write( 0, wbxmlDataPtr );
+
+ CleanupStack::PopAndDestroy( wbxmlDataBuf );
+ }
+ CleanupStack::PopAndDestroy( &file );
+ LOGGER_WRITE_1( "CSConFTP::ReadWBXMLData( CBufFlat*& aBuffer ) : WBXML packet size: %d", fileSize );
+
+ LOGGER_WRITE_1( "CSConFTP::ReadWBXMLData( CBufFlat*& aBuffer ) : returned %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::DeleteTempFile()
+// Delete OBEX stack's temp file
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::DeleteTempFile()
+ {
+ TRACE_FUNC_ENTRY;
+ iFs.Delete( iTempFileName );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::MoveFile()
+// Move file/folder
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::MoveFile(const TDesC& aSource, const TDesC& aTarget)
+ {
+ TRACE_FUNC_ENTRY;
+ TInt err;
+ TFileName tmpSource;
+ TFileName tmpTarget;
+ err = GetAbsolutePath( aSource, tmpSource );
+ if( err == KErrNone )
+ {
+ err = GetAbsolutePath( aTarget, tmpTarget );
+ }
+
+ if( err == KErrNone )
+ {
+ TInt sourceDrive;
+ TInt targetDrive;
+
+ err = iFs.CharToDrive( tmpSource[0], sourceDrive );
+ TInt err2 = iFs.CharToDrive( tmpTarget[0], targetDrive );
+
+ if( err != KErrNone || err2 != KErrNone
+ || !IsDriveVisible( sourceDrive )
+ || !IsDriveVisible( targetDrive ) )
+ {
+ // drive not visible to user
+ err = KErrNotFound;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ TRAP( err,
+ iSConFsHandler->DoCopyOrMoveFileL( tmpSource, tmpTarget, EFalse ) );
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::MoveFile() : end, err: %d", err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::CopyFile()
+// Copy file/folder
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::CopyFile(const TDesC& aSource, const TDesC& aTarget)
+ {
+ TRACE_FUNC_ENTRY;
+ TInt err;
+ TFileName tmpSource;
+ TFileName tmpTarget;
+ err = GetAbsolutePath( aSource, tmpSource );
+ if (err == KErrNone)
+ {
+ err = GetAbsolutePath( aTarget, tmpTarget );
+ }
+
+ if( err == KErrNone )
+ {
+ TInt sourceDrive;
+ TInt targetDrive;
+
+ err = iFs.CharToDrive( tmpSource[0], sourceDrive );
+ TInt err2 = iFs.CharToDrive( tmpTarget[0], targetDrive );
+
+ if( err != KErrNone || err2 != KErrNone
+ || !IsDriveVisible( sourceDrive )
+ || !IsDriveVisible( targetDrive ) )
+ {
+ // drive not visible to user
+ err = KErrNotFound;
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ TRAP( err,
+ iSConFsHandler->DoCopyOrMoveFileL( tmpSource, tmpTarget, ETrue ) );
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::CopyFile() : end, ret: %d", err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetReadOnly()
+// Set read-only permissions to file or folder
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::SetReadOnly(const TDesC& aTarget, const TBool aReadOnly)
+ {
+ TRACE_FUNC_ENTRY;
+ TInt err;
+ TFileName tmpTarget;
+ err = GetAbsolutePath( aTarget, tmpTarget );
+ if( err != KErrNone )
+ {
+ return err;
+ }
+ else
+ {
+ TInt targetDrive;
+ err = iFs.CharToDrive( tmpTarget[0], targetDrive );
+
+ if( err != KErrNone
+ || !IsDriveVisible( targetDrive ) )
+ {
+ // drive not visible to user
+ return KErrNotFound;
+ }
+ }
+
+ TBool isFolder(EFalse);
+ err = BaflUtils::IsFolder( iFs, tmpTarget, isFolder );
+ if ( err == KErrNone && isFolder )
+ {
+ tmpTarget.Append(KPathDelimiter);
+ }
+ if ( !iSConFsHandler->IsFolderVisible( tmpTarget ) )
+ {
+ // folder is not visible to user
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ if( aReadOnly )
+ {
+ err = iFs.SetAtt( tmpTarget, KEntryAttReadOnly, KEntryAttArchive );
+ }
+ else
+ {
+ err = iFs.SetAtt( tmpTarget, KEntryAttNormal, KEntryAttReadOnly );
+ }
+ }
+
+ LOGGER_WRITE_1( "CSConFTP::SetReadOnly() : ret: %d", err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::SetHidden()
+// Set hidden permissions to file or folder
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::SetHidden( const TDesC& /*aTarget*/, const TBool /*aHidden*/ )
+ {
+ // This is currently not supported.
+ LOGGER_WRITE("CSConFTP::SetHidden return KErrNotSupported");
+ return KErrNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::GetAbsolutePath()
+// Get absolute path from relative file/folder
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::GetAbsolutePath( const TDesC& aFolderName, TDes &aFullPath )
+ {
+ if (aFolderName.Length() == 0)
+ {
+ return KErrBadName;
+ }
+ //absolute folder path
+ if( aFolderName.Length() > 1 && aFolderName[1] == KDriveDelimiter )
+ {
+ aFullPath.Copy( aFolderName );
+ }
+ // relative to the root folder
+ else if( aFolderName[0] == KPathDelimiter )
+ {
+ if( iPathName.Length() < 2 )
+ {
+ return KErrBadName;
+ }
+ aFullPath.Copy( iPathName.Left(2) );
+ aFullPath.Append( aFolderName );
+ }
+ // relative to the current folder
+ else
+ {
+ aFullPath.Copy( iPathName );
+ if( aFullPath.LocateReverse( KPathDelimiter ) != aFullPath.Length()-1 )
+ {
+ aFullPath.Append( KPathDelimiter );
+ }
+ aFullPath.Append( aFolderName );
+ // no need to check internal root, because iPathName is real target.
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::CSConFTP()
+// Default constructor
+// -----------------------------------------------------------------------------
+//
+CSConFTP::CSConFTP() : iProfile( EStandard ), iCurrentDrive( KErrNotFound )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::ConstructL()
+// Initializes member data
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::ConstructL()
+ {
+ TRACE_FUNC_ENTRY;
+
+ iBuffer = CBufFlat::NewL( KSConBufSize );
+ User::LeaveIfError( iFs.Connect() );
+ iSConFsHandler = CSConFsHandler::NewL( iFs );
+ iSConInboxHandler = CSConInboxHandler::NewL();
+
+ CRepository* repository = CRepository::NewLC( KCRUidDiskLevel );
+ User::LeaveIfError( repository->Get( KDiskCriticalThreshold, iCriticalDiskLevel ) );
+ CleanupStack::PopAndDestroy( repository );
+ // inlcude package size
+ iCriticalDiskLevel += KPackageSize;
+ LOGGER_WRITE_1( "criticalLevel: %d", iCriticalDiskLevel );
+
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::GetVolumeNameL()
+// Get volume name
+// -----------------------------------------------------------------------------
+//
+TInt CSConFTP::GetVolumeNameL(const TInt aDriveNumber, TDes8& aVolumeName)
+ {
+ TRACE_FUNC_ENTRY;
+ TVolumeInfo volumeInfo;
+ TInt ret = iFs.Volume( volumeInfo, aDriveNumber );
+
+ if ( ret == KErrNone)
+ {
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( aVolumeName,
+ volumeInfo.iName );
+ //Replace special characters
+ for( TInt i = 0; i < aVolumeName.Length(); i++ )
+ {
+ switch( aVolumeName[i] )
+ {
+ case '&':
+ aVolumeName.Delete( i, 1 );
+ aVolumeName.Insert( i, KReplace1 );
+ break;
+ case '<':
+ aVolumeName.Delete( i, 1 );
+ aVolumeName.Insert( i, KReplace2 );
+ break;
+ case '>':
+ aVolumeName.Delete( i, 1 );
+ aVolumeName.Insert( i, KReplace3 );
+ break;
+ case '"':
+ aVolumeName.Delete( i, 1 );
+ aVolumeName.Insert( i, KReplace4 );
+ break;
+ case '\'':
+ aVolumeName.Delete( i, 1 );
+ aVolumeName.Insert( i, KReplace5 );
+ break;
+ default:
+ break;
+ }
+ }
+
+ //No name
+ if( aVolumeName.Length() == 0 )
+ {
+ LOGGER_WRITE( "Volume has no name, use default localized name" );
+ //Read memory string and convert it
+ TFileName file( KSConResourceName );
+
+ BaflUtils::NearestLanguageFile( iFs, file );
+
+ CStringResourceReader* reader = CStringResourceReader::NewL( file );
+ CleanupStack::PushL( reader );
+ TUint driveStatus;
+ User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, aDriveNumber, driveStatus ) );
+ if( driveStatus & DriveInfo::EDriveRemovable )
+ {
+ // read default MMC name
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( aVolumeName,
+ reader->ReadResourceString( R_SECON_VALUE_MMC ) );
+ }
+ else
+ {
+ // read default DEV name
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( aVolumeName,
+ reader->ReadResourceString( R_SECON_VALUE_DEVICE ) );
+ }
+ CleanupStack::PopAndDestroy( reader );
+ }
+ }
+ LOGGER_WRITE_1("GetVolumeNameL returned: %d", ret);
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::IsDriveVisible()
+// Check is drive visible for user
+// -----------------------------------------------------------------------------
+//
+TBool CSConFTP::IsDriveVisible( const TInt aDriveNumber )
+ {
+ TUint driveStatus;
+ TInt err = DriveInfo::GetDriveStatus( iFs, aDriveNumber, driveStatus);
+ if( err )
+ {
+ LOGGER_WRITE_1( "CSConFTP::IsDriveVisible() : DriveInfo::GetDriveStatus err: %d", err );
+ return EFalse;
+ }
+ if( driveStatus & DriveInfo::EDriveRemote )
+ {
+ LOGGER_WRITE( "CSConFTP::IsDriveVisible() : remote drive" );
+ return EFalse;
+ }
+ if( !(driveStatus & DriveInfo::EDriveUserVisible) )
+ {
+ LOGGER_WRITE( "CSConFTP::IsDriveVisible() : not visible" );
+ return EFalse;
+ }
+ if( !(driveStatus & DriveInfo::EDrivePresent ) )
+ {
+ LOGGER_WRITE( "CSConFTP::IsDriveVisible() : not present" );
+ return EFalse;
+ }
+ if( driveStatus & DriveInfo::EDriveCorrupt )
+ {
+ LOGGER_WRITE( "CSConFTP::IsDriveVisible() : corrupted" );
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::UpdateDriveTypeInfoL()
+// Test is current volume still ok.
+// -----------------------------------------------------------------------------
+//
+TBool CSConFTP::IsCurrentVolumeOK()
+ {
+ if( iCurrentDrive == KErrNotFound )
+ {
+ LOGGER_WRITE( "CSConFTP::IsCurrentVolumeOK() : not set" );
+ return EFalse;
+ }
+
+ TUint driveStatus;
+ TInt err = DriveInfo::GetDriveStatus( iFs, iCurrentDrive, driveStatus);
+ if( err )
+ {
+ LOGGER_WRITE_1( "CSConFTP::IsCurrentVolumeOK() : DriveInfo::GetDriveStatus err: %d", err );
+ return EFalse;
+ }
+ if( !(driveStatus & DriveInfo::EDrivePresent ))
+ {
+ LOGGER_WRITE( "CSConFTP::IsCurrentVolumeOK() : not present" );
+ return EFalse;
+ }
+ if( driveStatus & DriveInfo::EDriveCorrupt )
+ {
+ LOGGER_WRITE( "CSConFTP::IsCurrentVolumeOK() : corrupted" );
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSConFTP::UpdateDriveTypeInfoL()
+// Updates drive information (iCurrentDrive and iCurrentDriveTypeNumber)
+// -----------------------------------------------------------------------------
+//
+void CSConFTP::UpdateDriveTypeInfoL()
+ {
+ TRACE_FUNC_ENTRY;
+ TInt driveNumber;
+ iCurrentDriveTypeNumber = 0;
+
+ if( iPathName.Length() == 0 )
+ {
+ LOGGER_WRITE( "CSConFTP::UpdateDriveTypeInfoL() : drive not specified" );
+ iCurrentDrive = KErrNotFound;
+ return;
+ }
+
+ User::LeaveIfError( iFs.CharToDrive(iPathName[0], driveNumber) );
+ iCurrentDrive = driveNumber;
+
+ TUint driveStatus;
+ User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, iCurrentDrive, driveStatus ) );
+ // if true, search internal drives, else search removable drives
+ TBool searchInternalDrives = (driveStatus & DriveInfo::EDriveInternal);
+
+ TInt driveCount;
+ TDriveList driveList;
+
+ User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) );
+
+ for( TInt i = EDriveA; i <= iCurrentDrive; i++ )
+ {
+ if( driveList[i] )
+ {
+ TUint driveStatus;
+ User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, i, driveStatus ) );
+
+ if( !(driveStatus & DriveInfo::EDrivePresent )
+ || driveStatus & DriveInfo::EDriveCorrupt )
+ {
+ LOGGER_WRITE( "not present or corrupted" );
+ continue;
+ }
+
+ if( driveStatus & DriveInfo::EDriveInternal )
+ {
+ if( searchInternalDrives )
+ {
+ iCurrentDriveTypeNumber++;
+ }
+ }
+ else if( driveStatus & DriveInfo::EDriveRemovable )
+ {
+ if( !searchInternalDrives )
+ {
+ iCurrentDriveTypeNumber++;
+ }
+ }
+ }
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// End of file
+