os/ossrv/lowlevellibsandfws/apputils/bsul/src/ccacheddriveinfo.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/lowlevellibsandfws/apputils/bsul/src/ccacheddriveinfo.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,231 @@
     1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Contains implementation of BSUL class to cache drive information
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +/**
    1.22 + @file
    1.23 +*/
    1.24 +
    1.25 +#include <bsul/ccacheddriveinfo.h>
    1.26 +
    1.27 +using namespace BSUL;
    1.28 +
    1.29 +/**
    1.30 + Constructs CCachedDriveInfo object by retrieving the drive status using aFs
    1.31 + @param aFs Reference to connected filesystem
    1.32 + */
    1.33 +EXPORT_C CCachedDriveInfo* CCachedDriveInfo::NewL(RFs& aFs)
    1.34 +	{
    1.35 +	CCachedDriveInfo *self = new(ELeave) CCachedDriveInfo();
    1.36 +	CleanupStack::PushL(self);
    1.37 +	self->ConstructL(aFs);
    1.38 +	CleanupStack::Pop(self);
    1.39 +	return self;
    1.40 +	}
    1.41 +
    1.42 +/**
    1.43 + Constructs CCachedDriveInfo object by retrieving the drive status using aFs
    1.44 + @param aFs Reference to connected filesystem
    1.45 + */
    1.46 +EXPORT_C CCachedDriveInfo* CCachedDriveInfo::NewLC(RFs& aFs)
    1.47 +	{
    1.48 +	CCachedDriveInfo *self = new(ELeave) CCachedDriveInfo();
    1.49 +	CleanupStack::PushL(self);
    1.50 +	self->ConstructL(aFs);
    1.51 +	return self;
    1.52 +	}
    1.53 +/**
    1.54 + @internalComponent
    1.55 + */
    1.56 +CCachedDriveInfo::CCachedDriveInfo()
    1.57 +	{}
    1.58 +
    1.59 +/**
    1.60 + @internalComponent
    1.61 + */
    1.62 +void CCachedDriveInfo::ConstructL(RFs& aFs)
    1.63 +	{
    1.64 +	// Goes through each drive, and stores whether or not it is available, 
    1.65 +	// the drive's attributes, and the drive's media attributes
    1.66 +	for (TDriveUnit drive(EDriveZ); drive >= EDriveA; drive = TInt(drive) - 1)
    1.67 +		{
    1.68 +		ASSERT(aFs.IsValidDrive(drive));
    1.69 +		
    1.70 +		TDriveInfo driveInfo;
    1.71 +		User::LeaveIfError(aFs.Drive(driveInfo, drive));
    1.72 +		iDriveAndMediaAttributes[drive].iDriveAttributes = driveInfo.iDriveAtt;
    1.73 +		iDriveAndMediaAttributes[drive].iMediaAttributes = driveInfo.iMediaAtt;
    1.74 +		iDriveAndMediaAttributes[drive].iMediaType = driveInfo.iType;
    1.75 +		}
    1.76 +	}
    1.77 +	
    1.78 +/**
    1.79 + Frees all allocated resources
    1.80 + */
    1.81 +EXPORT_C CCachedDriveInfo::~CCachedDriveInfo()
    1.82 +	{
    1.83 +	}
    1.84 +
    1.85 +/**
    1.86 + @internalComponent
    1.87 + Returns the TDriveUnit associated with the given path
    1.88 + @param aFullName File name that includes a drive
    1.89 + @return The drive unit associated with aFullName
    1.90 + @leave Leaves with a system-wide error code if the aFullName cannot be parsed,
    1.91 + 		or with KErrBadName if the supplied path does not contain a drive letter
    1.92 + */
    1.93 +TDriveUnit CCachedDriveInfo::PathToDriveUnitL(const TDesC& aFullName)
    1.94 +	{
    1.95 +	// check if the filename can be parsed
    1.96 +	TParse checkParse;
    1.97 +	TInt retcode = checkParse.Set(aFullName, NULL, NULL);
    1.98 +	User::LeaveIfError(retcode);
    1.99 +	
   1.100 +	TParsePtrC parse(aFullName);
   1.101 +	if (!parse.DrivePresent())
   1.102 +		{
   1.103 +		User::Leave(KErrBadName);
   1.104 +		}
   1.105 +	
   1.106 +	TDriveUnit driveId(aFullName);
   1.107 +	
   1.108 +	return driveId;
   1.109 +	}
   1.110 +
   1.111 +/**
   1.112 + Checks if the drive associated with aFullName is both read-only and internal by 
   1.113 + checking that the KMediaAttWriteProtected and KDriveAttInternal flags are both set.
   1.114 +
   1.115 + @param aFullName File name that includes a drive
   1.116 + @return Returns ETrue if the drive is read-only and internal, EFalse otherwise (including when the drive is not mounted)
   1.117 + @leave Leaves with a system-wide error code if the aFullName cannot be parsed,
   1.118 + 		or with KErrBadName if the supplied path does not contain a drive letter
   1.119 + */
   1.120 +EXPORT_C TBool CCachedDriveInfo::IsReadOnlyInternalL(const TDesC& aFullName) const
   1.121 +	{
   1.122 +	TDriveUnit driveId = PathToDriveUnitL(aFullName);
   1.123 +	
   1.124 +	return IsReadOnlyInternalL(driveId);
   1.125 +	}
   1.126 +
   1.127 +/**
   1.128 + Checks if the specified drive is both read-only and internal by checking that the 
   1.129 + KMediaAttWriteProtected and KDriveAttInternal flags are both set.
   1.130 +
   1.131 + @param aDrive The drive whose read-only status is being retrieved
   1.132 + @return Returns ETrue if the drive is read-only and internal, EFalse otherwise (including when the drive is not mounted)
   1.133 + @leave Leaves with KErrBadName if aDrive is not a valid drive between EDriveA and EDriveZ
   1.134 + */
   1.135 +EXPORT_C TBool CCachedDriveInfo::IsReadOnlyInternalL(TDriveUnit aDrive) const
   1.136 +	{
   1.137 +	if (aDrive < EDriveA || aDrive > EDriveZ)
   1.138 +		{
   1.139 +		User::Leave(KErrBadName);
   1.140 +		}
   1.141 +
   1.142 +	if ( (iDriveAndMediaAttributes[aDrive].iDriveAttributes & KDriveAttInternal) &&
   1.143 +		 (iDriveAndMediaAttributes[aDrive].iMediaAttributes & KMediaAttWriteProtected) )
   1.144 +		{
   1.145 +		return ETrue;
   1.146 +		}
   1.147 +	
   1.148 +	return EFalse;
   1.149 +	}
   1.150 +
   1.151 +/**
   1.152 + This method allows the caller to test the attributes of a drive to see if 
   1.153 + they are set. For example, a drive can be check whether it is remote by 
   1.154 + checking the flag KDriveAttRemote is set.
   1.155 + Valid flags are those defined in e32const.h starting KDriveAtt*
   1.156 +
   1.157 + @see TDriveInfo
   1.158 + @param aDrive The drive whose attribute information is being tested
   1.159 + @param aFlags The attributes to be checked for the drive
   1.160 + @return ETrue if attributes in the drive are set, EFalse otherwise 
   1.161 + @leave KErrBadName if aDrive is not a valid drive between EDriveA and EDriveZ
   1.162 + */
   1.163 +EXPORT_C TBool CCachedDriveInfo::IsFlagSetOnDriveL(TDriveUnit aDrive, TUint aFlags) const
   1.164 +	{
   1.165 +	if (aDrive < EDriveA || aDrive > EDriveZ)
   1.166 +		{
   1.167 +		User::Leave(KErrBadName);
   1.168 +		}
   1.169 +
   1.170 +	return ((iDriveAndMediaAttributes[aDrive].iDriveAttributes & aFlags) == aFlags) ? ETrue : EFalse;
   1.171 +	}
   1.172 +		
   1.173 +/**
   1.174 + This method allows the caller to check the media type of a drive, to 
   1.175 + see if a drive is of a particular media type. It also optionally
   1.176 + returns the media type of the drive.
   1.177 +  
   1.178 + @see TDriveInfo
   1.179 + @param aDrive The drive whose media type information is being checked.
   1.180 + @param aTestValue The media type to compare against the drive provided.
   1.181 + @param aActual return parameter - if the caller provides a pointer
   1.182 + for this parameter type, then it will be populated with the actual media type
   1.183 + of the drive. This is useful to avoid repeated queries if the media type
   1.184 + is needed.
   1.185 + @return ETrue if the drive media type matches the media type provided
   1.186 + @leave KErrBadName if aDrive is not a valid drive between EDriveA and EDriveZ
   1.187 + */
   1.188 +EXPORT_C TBool CCachedDriveInfo::MediaTypeL(TDriveUnit aDrive, TMediaType aTestValue, TMediaType* aActual) const
   1.189 +	{
   1.190 +	if (aDrive < EDriveA || aDrive > EDriveZ)
   1.191 +		{
   1.192 +		User::Leave(KErrBadName);
   1.193 +		}
   1.194 +	
   1.195 +	if (aActual)
   1.196 +		{
   1.197 +		*aActual = iDriveAndMediaAttributes[aDrive].iMediaType;
   1.198 +		}
   1.199 +	
   1.200 +	return (iDriveAndMediaAttributes[aDrive].iMediaType == aTestValue) ? ETrue : EFalse;
   1.201 +	}
   1.202 +
   1.203 +/**
   1.204 + This method fetches the default removable memory card (MMC card). To determine
   1.205 + the MMC drive a default algorithm will be used.
   1.206 +
   1.207 + The algorithm to be used will be to search through the drive list provided
   1.208 + by RFs for the first drive that has the following properties 
   1.209 + 1) Drive type is EMediaHardDisk
   1.210 + 2) Drive attributes are KDriveAttRemovable and KDriveAttLocal
   1.211 +  
   1.212 + @see TDriveInfo
   1.213 + @return TDriveUnit The drive found by the algorithm
   1.214 + @leave KErrNotFound if drive not found
   1.215 + */
   1.216 +EXPORT_C TDriveUnit CCachedDriveInfo::GetDefaultRemovableMemoryCardDriveL() const
   1.217 +	{
   1.218 +	for (TInt driveNum=EDriveA; driveNum<=EDriveZ; driveNum++)
   1.219 +		{
   1.220 +	    // Confirmed on H4 board that the properties below were present for an MMC card. Also
   1.221 +		// E32 has a test PBASE-T_MMCDRV-0164 that also confirms this.
   1.222 +		if (IsFlagSetOnDriveL(driveNum, KDriveAttRemovable|KDriveAttLocal) &&
   1.223 +	        MediaTypeL(driveNum, EMediaHardDisk))
   1.224 +			{
   1.225 +			// Found MMC drive.
   1.226 +			return driveNum;
   1.227 +			}
   1.228 +	    }
   1.229 +
   1.230 +	// No valid MMC drive available.
   1.231 +	User::Leave(KErrNotFound);
   1.232 +	return -1; // to avoid warning
   1.233 +	}
   1.234 +