connectivitymodules/SeCon/services/ftp/src/sconftp.cpp
branchRCL_3
changeset 20 4a793f564d72
--- /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
+