commonservices/PlatformEnv/src/driveinfo.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commonservices/PlatformEnv/src/driveinfo.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,578 @@
+/*
+* Copyright (c) 2007-2009 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:  Holds the drive information of the system.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "driveinfo.h"
+#include "driveinfopatchdata.h"
+#include "platformenvdebug.h"
+
+// CONSTANTS
+const TInt KMaxFsName = 256;
+_LIT( KMsFsName, "MassStorageFileSystem" );
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// IsUserHiddenDrive
+// -----------------------------------------------------------------------------
+//
+static TBool IsUserHiddenDrive( TInt aDrive )
+    {
+    FUNC_LOG
+
+    return ( aDrive >= 0 &&
+             ( aDrive == KDriveInfoUserHiddenDrive1 ||
+               aDrive == KDriveInfoUserHiddenDrive2 ||
+               aDrive == KDriveInfoUserHiddenDrive3 ||
+               aDrive == KDriveInfoUserHiddenDrive4 ||
+               aDrive == KDriveInfoUserHiddenDrive5 ||
+               aDrive == KDriveInfoUserHiddenDrive6 ||
+               aDrive == KDriveInfoUserHiddenDrive7 ||
+               aDrive == KDriveInfoUserHiddenDrive8 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// IsUsbDrive
+// -----------------------------------------------------------------------------
+//
+static TBool IsUsbDrive( TInt aDrive )
+    {
+    FUNC_LOG
+
+    return ( aDrive >= 0 &&
+             aDrive >= KDriveInfoUsbDrivesStart &&
+             aDrive < KDriveInfoUsbDrivesStart + KDriveInfoUsbDrivesMaxCount );
+    }
+
+// -----------------------------------------------------------------------------
+// ExternallyMountableInternalDrive
+// -----------------------------------------------------------------------------
+//
+static TBool ExternallyMountableInternalDrive( TInt aDrive, TInt aDriveAtt )
+    {
+    FUNC_LOG
+
+    if ( aDriveAtt & KDriveAttLogicallyRemovable )
+        {
+        return ETrue;
+        }
+
+    return ( aDrive >= 0 &&
+             ( aDrive == KDriveInfoLogicallyRemovableDrive1 ||
+               aDrive == KDriveInfoLogicallyRemovableDrive2 ||
+               aDrive == KDriveInfoLogicallyRemovableDrive3 ||
+               aDrive == KDriveInfoLogicallyRemovableDrive4 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// MassStorageFsInUse
+// -----------------------------------------------------------------------------
+//
+static TBool MassStorageFsInUse( TInt aDrive, TInt aDriveAtt, RFs& aFs )
+    {
+    FUNC_LOG
+
+    if ( !( aDriveAtt & KDriveAttRemovable ) )
+        {
+        return EFalse;
+        }
+    HBufC* buffer = HBufC::New( KMaxFsName );
+    if ( !buffer )
+        {
+        return EFalse;
+        }
+    TBool ret( EFalse );
+    TPtr ptr( buffer->Des() );
+    if ( aFs.FileSystemName( ptr, aDrive ) == KErrNone )
+        {
+        if ( !ptr.CompareF( KMsFsName ) )
+            {
+            ret = ETrue;
+            }
+        }
+    delete buffer;
+    return ret;
+    }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetDefaultDrive
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetDefaultDrive( TInt aDefaultDrive, TInt& aDrive )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TInt ret( KErrNone );
+    switch ( aDefaultDrive )
+        {
+        case DriveInfo::EDefaultRom:
+            ret = KDriveInfoDefaultRomDrive;
+            break;
+        case DriveInfo::EDefaultRam:
+            ret = KDriveInfoDefaultRamDrive;
+            break;
+        case DriveInfo::EDefaultSystem:
+            ret = KDriveInfoDefaultSystemDrive >= 0 ?
+                  KDriveInfoDefaultSystemDrive : RFs::GetSystemDrive();
+            break;
+        case DriveInfo::EDefaultPhoneMemory:
+            ret = KDriveInfoDefaultPhoneMemory;
+            break;
+        case DriveInfo::EDefaultMassStorage:
+            ret = KDriveInfoDefaultMassStorage;
+            break;
+        case DriveInfo::EDefaultRemovableMassStorage:
+            ret = KDriveInfoDefaultRemovableMassStorage;
+            break;
+        default:
+            ret = KErrArgument;
+            break;
+        }
+
+    if ( ret >= 0 )
+        {
+        aDrive = ret;
+        ret = KErrNone;
+        }
+
+    INFO_LOG2( "DriveInfo::GetDefaultDrive-aDefaultDrive=%d,aDrive=%d",
+        aDefaultDrive, aDrive )
+
+    LOG_IF_ERROR2( ret,
+        "DriveInfo::GetDefaultDrive-aDefaultDrive=%d,ret=%d",
+        aDefaultDrive, ret )
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetDriveStatus
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetDriveStatus(
+        RFs& aFs, TInt aDrive, TUint& aStatus )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    aStatus = 0;
+
+    if ( !RFs::IsValidDrive( aDrive ) )
+        {
+        ERROR_LOG2( "DriveInfo::GetDriveStatus-aDrive=%d,IsValidDriveRet=%d",
+            aDrive, KErrArgument )
+
+        return KErrArgument;
+        }
+
+    // Get volume info
+    TVolumeInfo volumeInfo;
+    TInt ret( aFs.Volume( volumeInfo, aDrive ) );
+
+    INFO_LOG2( "DriveInfo::GetDriveStatus-aDrive=%d,VolumeInfoRet=%d",
+        aDrive, ret )
+
+    switch( ret )
+        {
+        case KErrNone:
+            {
+            if ( volumeInfo.iDrive.iType != EMediaNotPresent )
+                {
+                aStatus |= EDrivePresent;
+                if( volumeInfo.iSize )
+                    {
+                    aStatus |= EDriveFormatted;
+                    }
+                }
+            else
+                {
+                ERROR_LOG1(
+                    "DriveInfo::GetDriveStatus-aDrive=%d,InvalidVolume",
+                    aDrive )
+                ret = KErrNotReady;
+                }
+            break;
+            }
+        case KErrLocked:
+            {
+            aStatus |= EDrivePresent | EDriveLocked | EDriveFormatted |
+                EDriveLockable | EDriveHasPassword;
+            break;
+            }
+        case KErrCorrupt:
+            {
+            aStatus |= EDrivePresent | EDriveCorrupt;
+            break;
+            }
+        case KErrInUse:
+            {
+            aStatus |= EDrivePresent | EDriveInUse;
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+
+    // Get drive info if not already done by volume info read
+    TDriveInfo& driveInfo( volumeInfo.iDrive );
+    if ( ret != KErrNone )
+        {
+        TInt err( aFs.Drive( driveInfo, aDrive ) );
+
+        INFO_LOG2( "DriveInfo::GetDriveStatus-aDrive=%d,DriveInfoRet=%d",
+            aDrive, err )
+
+        if ( err != KErrNone )
+            {
+            ERROR_LOG2( "DriveInfo::GetDriveStatus-aDrive=%d,DriveInfoRet=%d",
+                aDrive, err )
+
+            return err; // Nothing can be done
+            }
+
+        // Mass storage mode may return some other error than KErrInUse in 
+        // volume info read. Check is mass storage file system in use.
+        if( driveInfo.iType != EMediaNotPresent &&
+            ret != KErrInUse &&
+            MassStorageFsInUse( aDrive, driveInfo.iDriveAtt, aFs ) )
+            {
+            INFO_LOG1( "DriveInfo::GetDriveStatus-aDrive=%d,DriveInUse",
+                aDrive )
+
+            aStatus |= EDrivePresent | EDriveInUse;
+            }
+        }
+
+    INFO_LOG3(
+        "DriveInfo::GetDriveStatus-DriveAttr=%d,MediaAttr=%d,MediaType=%d",
+        driveInfo.iDriveAtt,
+        driveInfo.iMediaAtt,
+        driveInfo.iType )
+
+    // If drive attributes are set, suppress volume read error
+    if ( driveInfo.iDriveAtt )
+        {
+        ret = KErrNone;
+        }
+
+    if ( !IsUserHiddenDrive( aDrive ) )
+        {
+        aStatus |= EDriveUserVisible;
+        }
+
+    // Check media type
+    TInt defaultRom( KErrNotFound );
+    GetDefaultDrive( EDefaultRom, defaultRom );
+    TInt defaultPhoneMem( KErrNotFound );
+    GetDefaultDrive( EDefaultPhoneMemory, defaultPhoneMem );
+
+    if ( driveInfo.iType == EMediaRom || defaultRom == aDrive )
+        {
+        aStatus |= EDriveRom | EDriveReadOnly;
+        }
+    // Default phone memory should always be non volatile media.
+    // If it is defined to RAM media, there is something wrong in 
+    // media configurations.
+    else if ( aDrive != defaultPhoneMem )
+        {
+        TInt defaultRam( KErrNotFound );
+        GetDefaultDrive( EDefaultRam, defaultRam );
+        if ( driveInfo.iType == EMediaRam || defaultRam == aDrive )
+            {
+            aStatus |= EDriveRam;
+            }
+        }
+
+    // Check drive attributes
+#ifdef __WINS__
+    // On emulator, handle memory card defined as local drive in epoc ini
+    // that has invalid drive attributes
+    TInt defaultRemovable( KErrNotFound );
+    GetDefaultDrive( EDefaultRemovableMassStorage, defaultRemovable );
+#endif // __WINS__
+
+    if ( ( driveInfo.iDriveAtt & KDriveAttInternal )
+#ifdef __WINS__
+          && ( defaultRemovable != aDrive ) 
+#endif // __WINS__
+          )
+        {
+        aStatus |= EDriveInternal;
+
+        // Note that internal mass storage may have 'internal' file
+        // server attribute
+        if ( ExternallyMountableInternalDrive( aDrive, driveInfo.iDriveAtt ) )
+            {
+            aStatus |= EDriveExternallyMountable;
+            }
+        }
+    else if ( ( driveInfo.iDriveAtt & KDriveAttRemovable )
+#ifdef __WINS__
+             || ( defaultRemovable == aDrive ) 
+#endif // __WINS__
+             )
+        {
+        // Note that internal mass storage may have 'removable' file
+        // server attribute
+        if ( ExternallyMountableInternalDrive( aDrive, driveInfo.iDriveAtt ) )
+            {
+            aStatus |= EDriveInternal | EDriveExternallyMountable;
+            }
+        else
+            {
+            aStatus |= EDriveRemovable | EDriveExternallyMountable |
+                EDriveSwEjectable;
+            if ( IsUsbDrive( aDrive ) )
+                {
+                aStatus |= EDriveUsbMemory;
+                }
+            }
+        }
+    else if ( driveInfo.iDriveAtt & KDriveAttRemote )
+        {
+        aStatus |= EDriveRemote | EDriveExternallyMountable;
+        }
+
+    if ( driveInfo.iDriveAtt & KDriveAttSubsted )
+        {
+        aStatus |= EDriveSubsted;
+        }
+
+    // Check media attributes
+    if ( driveInfo.iMediaAtt & KMediaAttLocked )
+        {
+        aStatus |= EDriveLocked;
+        }
+
+    if ( driveInfo.iMediaAtt & KMediaAttWriteProtected )
+        {
+        aStatus |= EDriveReadOnly;
+        }
+
+    if ( !( aStatus & EDriveReadOnly ) &&
+        ( driveInfo.iMediaAtt & KMediaAttFormattable ) )
+        {
+        aStatus |= EDriveFormattable;
+        }
+
+    if ( !( aStatus & EDriveInternal ) &&
+        ( driveInfo.iMediaAtt & KMediaAttLockable ) )
+        {
+        aStatus |= EDriveLockable;
+        }
+
+    if ( driveInfo.iMediaAtt & EDriveHasPassword )
+        {
+        aStatus |= EDriveHasPassword;
+        }
+
+    INFO_LOG3( "DriveInfo::GetDriveStatus-aDrive=%d,aStatus=0x%x,ret=%d",
+        aDrive, aStatus, ret )
+
+    LOG_IF_ERROR2( ret, "DriveInfo::GetDriveStatus-aDrive=%d,ret=%d",
+        aDrive, ret )
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetUserVisibleDrives
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetUserVisibleDrives(
+        RFs& aFs, TDriveList& aDriveList, TInt& aDriveCount )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    return GetUserVisibleDrives(
+        aFs, aDriveList, aDriveCount, KDriveAttExclude | KDriveAttRemote );
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetUserVisibleDrives
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetUserVisibleDrives(
+        RFs& aFs, TDriveList& aDriveList, TInt& aDriveCount, TUint aFlags )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    aDriveCount = 0;
+
+    TInt ret( aFs.DriveList( aDriveList, aFlags ) );
+    if ( ret == KErrNone )
+        {
+        aDriveCount = StripUserHiddenDrives( aDriveList );
+        }
+
+    INFO_LOG2( "DriveInfo::GetUserVisibleDrives-aDriveCount=%d,aFlags=%d",
+        aDriveCount, aFlags )
+
+    LOG_IF_ERROR1( ret, "DriveInfo::GetUserVisibleDrives-ret=%d", ret )
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::StripUserHiddenDrives
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::StripUserHiddenDrives( TDriveList& aDriveList )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TInt ret( 0 );
+    TInt count( aDriveList.Length() );
+    for( TInt i( 0 ); i < count; ++i )
+        {
+        if ( aDriveList[ i ] )
+            {
+            if ( !IsUserHiddenDrive( i ) )
+                {
+                ++ret;
+                }
+            else
+                {
+                aDriveList[ i ] = 0; // Remove user hidden drive
+                }
+            }
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::DriveCount
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::DriveCount( const TDriveList& aDriveList )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TInt ret( 0 );
+    TInt count( aDriveList.Length() );
+    for( TInt i( 0 ); i < count; ++i )
+        {
+        if ( aDriveList[ i ] )
+            {
+            ++ret;
+            }
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::TDriveArray::Set
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void DriveInfo::TDriveArray::Set( const TDriveList& aDriveList )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    iArray.Zero();
+    TInt count( Min( aDriveList.Length(), KMaxDrives ) );
+    for( TInt i( 0 ); i < count; ++i )
+        {
+        if ( aDriveList[ i ] )
+            {
+            iArray.Append( static_cast< TUint8 >( i ) );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::TDriveArray::LetterAt
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TChar DriveInfo::TDriveArray::LetterAt( TInt aIndex ) const
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TChar ret( 0 );
+    // Ignore return value, Set() guarantees that valid drives are used
+    RFs::DriveToChar( iArray[ aIndex ], ret );
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetUserVisibleDrives
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetUserVisibleDrives(
+        RFs& aFs, TDriveArray& aDriveArray )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    return GetUserVisibleDrives( aFs, aDriveArray, KDriveAttAll );
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetUserVisibleDrives
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetUserVisibleDrives(
+        RFs& aFs, TDriveArray& aDriveArray, TUint aFlags )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TDriveList drvList;
+    TInt ret( aFs.DriveList( drvList, aFlags ) );
+    if ( ret == KErrNone )
+        {
+        StripUserHiddenDrives( drvList );
+        aDriveArray.Set( drvList );
+        }
+    else
+        {
+        aDriveArray.Reset();
+        }
+
+    INFO_LOG2( "DriveInfo::GetUserVisibleDrives-aDriveArrayCount=%d,aFlags=%d",
+        aDriveArray.Count(), aFlags )
+
+    LOG_IF_ERROR1( ret, "DriveInfo::GetUserVisibleDrives-ret=%d", ret )
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DriveInfo::GetDefaultDrive
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt DriveInfo::GetDefaultDrive(
+        TInt aDefaultDrive, TChar& aDriveLetter )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TInt drive( 0 );
+    TInt ret( GetDefaultDrive( aDefaultDrive, drive ) );
+    if ( ret == KErrNone )
+        {
+        ret = RFs::DriveToChar( drive, aDriveLetter );
+        }
+
+    LOG_IF_ERROR1( ret, "DriveInfo::GetDefaultDrive-ret=%d", ret )
+
+    return ret;
+    }
+
+//  End of File