| 0 |      1 | // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
 | 
|  |      2 | // All rights reserved.
 | 
|  |      3 | // This component and the accompanying materials are made available
 | 
|  |      4 | // under the terms of the License "Eclipse Public License v1.0"
 | 
|  |      5 | // which accompanies this distribution, and is available
 | 
|  |      6 | // at the URL "http://www.eclipse.org/legal/epl-v10.html".
 | 
|  |      7 | //
 | 
|  |      8 | // Initial Contributors:
 | 
|  |      9 | // Nokia Corporation - initial contribution.
 | 
|  |     10 | //
 | 
|  |     11 | // Contributors:
 | 
|  |     12 | //
 | 
|  |     13 | // Description:
 | 
|  |     14 | // f32\sfile\sf_drv.cpp
 | 
|  |     15 | // 
 | 
|  |     16 | //
 | 
|  |     17 | 
 | 
|  |     18 | #include "sf_std.h"
 | 
|  |     19 | #include "sf_file_cache.h"
 | 
|  |     20 | #include <hal.h>
 | 
|  |     21 | 
 | 
|  |     22 | 
 | 
|  |     23 | 
 | 
|  |     24 | //const TInt KMaxNotifierAttempts=4; // not used anywhere
 | 
|  |     25 | 
 | 
|  |     26 | static TPtrC StripBackSlash(const TDesC& aName)
 | 
|  |     27 | //
 | 
|  |     28 | // If aName ends in a backslash, strip it.
 | 
|  |     29 | //
 | 
|  |     30 | 	{
 | 
|  |     31 | 
 | 
|  |     32 | 	__ASSERT_DEBUG(aName.Length(),Fault(EStripBackSlashBadName));
 | 
|  |     33 | 	if (aName[aName.Length()-1]==KPathDelimiter)
 | 
|  |     34 | 		return(aName.Left(aName.Length()-1));
 | 
|  |     35 | 	return(aName);
 | 
|  |     36 | 	}
 | 
|  |     37 | 
 | 
|  |     38 | static void CheckSubClose(CFsObject* anObj,TInt aHandle, CSessionFs* aSession)
 | 
|  |     39 | //
 | 
|  |     40 | // Close anObj if its not NULL.
 | 
|  |     41 | //
 | 
|  |     42 | 	{
 | 
|  |     43 | 	__PRINT1(_L("CheckSubClose() session 0x0%x"),aSession);
 | 
|  |     44 | 	__PRINT1(_L("CheckSubClose() anObj 0x0%x"),anObj);
 | 
|  |     45 | 
 | 
|  |     46 | 	if(!anObj)
 | 
|  |     47 | 		return;
 | 
|  |     48 | 
 | 
|  |     49 | 	if(aHandle==0)
 | 
|  |     50 | 		{
 | 
|  |     51 | 		// can't have been added to the object index
 | 
|  |     52 | 		__ASSERT_DEBUG(KErrNotFound==aSession->Handles().At(anObj,ETrue),Fault(ESubOpenBadHandle));
 | 
|  |     53 | 		anObj->Close();
 | 
|  |     54 | 		}
 | 
|  |     55 | 	else
 | 
|  |     56 | 		aSession->Handles().Remove(aHandle,ETrue);
 | 
|  |     57 | 	}
 | 
|  |     58 | 
 | 
|  |     59 | TInt ValidateDrive(TInt aDriveNumber,CFsRequest* aRequest)
 | 
|  |     60 | //
 | 
|  |     61 | // Validate a drive number and set iTheDrive.
 | 
|  |     62 | //
 | 
|  |     63 | 	{
 | 
|  |     64 | 	__CHECK_MAINTHREAD();
 | 
|  |     65 | 	if (aDriveNumber==KDefaultDrive)
 | 
|  |     66 | 		aDriveNumber=aRequest->Session()->CurrentDrive();
 | 
|  |     67 | 	if (!RFs::IsValidDrive(aDriveNumber))
 | 
|  |     68 | 		return(KErrBadName);
 | 
|  |     69 | 	aRequest->SetDrive(&TheDrives[aDriveNumber]);
 | 
|  |     70 | 	return(KErrNone);
 | 
|  |     71 | 	}
 | 
|  |     72 | 
 | 
|  |     73 | TInt ValidateDriveDoSubst(TInt aDriveNumber,CFsRequest* aRequest)
 | 
|  |     74 | //
 | 
|  |     75 | // Validate a drive number and set iTheDrive.
 | 
|  |     76 | //
 | 
|  |     77 | 	{
 | 
|  |     78 | 
 | 
|  |     79 | 	TInt r=ValidateDrive(aDriveNumber,aRequest);
 | 
|  |     80 | 	if (r!=KErrNone)
 | 
|  |     81 | 		return(r);
 | 
|  |     82 | 	if (aRequest->Drive()->IsSubsted())
 | 
|  |     83 | 		{
 | 
|  |     84 | 		aRequest->SetSubstedDrive(aRequest->Drive());
 | 
|  |     85 | 		aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
 | 
|  |     86 | 		}
 | 
|  |     87 | 	return(KErrNone);
 | 
|  |     88 | 	}
 | 
|  |     89 | 
 | 
|  |     90 | void ValidateAtts(TUint /*anEntryAtts*/,TUint& aSetAttMask,TUint& aClearAttMask)
 | 
|  |     91 | //
 | 
|  |     92 | // Do not allow the entry type to be changed
 | 
|  |     93 | //
 | 
|  |     94 | 	{
 | 
|  |     95 | 	const TUint KReadOnlySetAtts = KEntryAttVolume | 
 | 
|  |     96 | 								   KEntryAttDir    | 
 | 
|  |     97 | 								   KEntryAttRemote;
 | 
|  |     98 | 
 | 
|  |     99 | 	const TUint KReadOnlyClrAtts = KEntryAttVolume | 
 | 
|  |    100 | 								   KEntryAttDir    | 
 | 
|  |    101 | 								   KEntryAttRemote | 
 | 
|  |    102 | 								   KEntryAttModified;
 | 
|  |    103 | 
 | 
|  |    104 | 	aSetAttMask   &= ~KReadOnlySetAtts;
 | 
|  |    105 | 	aClearAttMask &= ~KReadOnlyClrAtts;
 | 
|  |    106 | 	}
 | 
|  |    107 | 
 | 
|  |    108 | void CheckForLeaveAfterOpenL(TInt leaveError, CFsRequest* aRequest, TInt aHandle)
 | 
|  |    109 | //
 | 
|  |    110 | // Tidy up in the event of a leave after opening a file or directory
 | 
|  |    111 | 	{
 | 
|  |    112 | 	if (leaveError)
 | 
|  |    113 | 		{
 | 
|  |    114 | 		CFsObject* anObj=(CFsObject* )aRequest->ScratchValue();
 | 
|  |    115 | 		CheckSubClose(anObj,aHandle,aRequest->Session());
 | 
|  |    116 | 		User::Leave(leaveError);
 | 
|  |    117 | 		}
 | 
|  |    118 | 	}
 | 
|  |    119 | 
 | 
|  |    120 | TDrive::TDrive()
 | 
|  |    121 | //
 | 
|  |    122 | // Constructor.
 | 
|  |    123 | //
 | 
|  |    124 | 	: iDriveNumber(0),iAtt(0),iChanged(EFalse),
 | 
|  |    125 | 	  iFSys(NULL),iCurrentMount(NULL),iSubstedDrive(NULL),iSubst(NULL),
 | 
|  |    126 | 	  iMount(NULL),iDriveFlags(0),iMountFailures(0)
 | 
|  |    127 | 	{}
 | 
|  |    128 | 
 | 
|  |    129 | void TDrive::CreateL(TInt aDriveNumber)
 | 
|  |    130 | //
 | 
|  |    131 | // Allocate the drive number and any resources.
 | 
|  |    132 | //
 | 
|  |    133 | 	{
 | 
|  |    134 | 	__PRINT1(_L("TDrive::CreateL(%d)"),aDriveNumber);
 | 
|  |    135 | 	iDriveNumber=aDriveNumber;
 | 
|  |    136 | 	iMount=TheContainer->CreateL();
 | 
|  |    137 | 	TInt r=iLock.CreateLocal();
 | 
|  |    138 | 	User::LeaveIfError(r);
 | 
|  |    139 | 	}
 | 
|  |    140 | 
 | 
|  |    141 | TInt TDrive::CheckMountAndEntryName(const TDesC& aName)
 | 
|  |    142 | //
 | 
|  |    143 | // Check drive is mounted then check aName is legal
 | 
|  |    144 | //
 | 
|  |    145 | 	{
 | 
|  |    146 | 
 | 
|  |    147 | 	__PRINT1(_L("TDrive::CheckMountAndEntryName Drive%d"),DriveNumber());
 | 
|  |    148 | 	TInt r=CheckMount();
 | 
|  |    149 | 	if (r==KErrNone && IsIllegalFullName(aName))
 | 
|  |    150 | 		return(KErrBadName);
 | 
|  |    151 | 	return(r);
 | 
|  |    152 | 	}
 | 
|  |    153 | 
 | 
|  |    154 | void TDrive::MultiSlotDriveCheck()
 | 
|  |    155 | 	{
 | 
|  |    156 | 	// Check whether the current drive is a dual-slot/multi-slot
 | 
|  |    157 | 	// if so, we need to check which drive is connected now and 
 | 
|  |    158 | 	// swap the mapping in LocalDrives::iMapping such that the 
 | 
|  |    159 | 	// mapping of driveNumber to localDriveNumber is correct.
 | 
|  |    160 | 
 | 
|  |    161 | 	Lock();
 | 
|  |    162 | 	//Is this a multislot drive?
 | 
|  |    163 | 	if(LocalDrives::iIsMultiSlotDrive[iDriveNumber])
 | 
|  |    164 | 		{
 | 
|  |    165 | 		for(TInt localDrvNum=0; localDrvNum<KMaxLocalDrives; localDrvNum++)
 | 
|  |    166 | 			{
 | 
|  |    167 | 			// ensure that this local drive is a multi-slot choice for this drive number..
 | 
|  |    168 | 			if(LocalDrives::iReverseMapping[localDrvNum]==iDriveNumber)
 | 
|  |    169 | 				{
 | 
|  |    170 | 				// Caps - find out which one is connected
 | 
|  |    171 | 				TLocalDriveCapsBuf capsInfo;
 | 
|  |    172 | 				TInt r = LocalDrives::iLocalDrives[localDrvNum].Caps(capsInfo);
 | 
|  |    173 | 				if(r==KErrNotReady)
 | 
|  |    174 | 					{
 | 
|  |    175 | 					continue; //go to next localdrive
 | 
|  |    176 | 					}
 | 
|  |    177 | 				//found a connected drive
 | 
|  |    178 | 				//Update mapping
 | 
|  |    179 | 				#ifdef _DEBUG
 | 
|  |    180 | 				RDebug::Print(_L("Multislot drive mapping update: DriveNum %d to LocDrv %d"),iDriveNumber,localDrvNum);
 | 
|  |    181 | 				#endif
 | 
|  |    182 | 				
 | 
|  |    183 | 				LocalDrives::iMapping[iDriveNumber] = localDrvNum;
 | 
|  |    184 | 				break; // Swap complete - don't look any further
 | 
|  |    185 | 				}
 | 
|  |    186 | 			}
 | 
|  |    187 | 		}	
 | 
|  |    188 | 	UnLock();
 | 
|  |    189 | 	}
 | 
|  |    190 | 
 | 
|  |    191 | TInt TDrive::CheckMount()
 | 
|  |    192 | //
 | 
|  |    193 | // Check the drive and try to mount a media if not already mounted.
 | 
|  |    194 | //
 | 
|  |    195 | 	{
 | 
|  |    196 | 	__PRINT2(_L("TDrive::CheckMount Drive%d, changed:%d"),DriveNumber(), iChanged);
 | 
|  |    197 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |    198 | 	
 | 
|  |    199 | 	if (!iFSys)
 | 
|  |    200 | 		return KErrNotReady;
 | 
|  |    201 | 		
 | 
|  |    202 | 	if (iChanged)				//	If a media change has occurred
 | 
|  |    203 | 		{
 | 
|  |    204 | 		iMountFailures = 0;
 | 
|  |    205 | 		iChanged=EFalse;		//	Reset the flag
 | 
|  |    206 | 		if (IsMounted())		//	Dismount the mount if it is still marked as mounted
 | 
|  |    207 | 			{
 | 
|  |    208 |             DoDismount();
 | 
|  |    209 | 			}
 | 
|  |    210 | 		//If we have a dual/multi removable media slot then we may need to
 | 
|  |    211 | 		//swop the mappings.
 | 
|  |    212 | 		MultiSlotDriveCheck();
 | 
|  |    213 | 		}
 | 
|  |    214 | 	
 | 
|  |    215 | 	if (!IsMounted())				//	Checks that iCurrentMount!=NULL
 | 
|  |    216 | 		{
 | 
|  |    217 | 		__PRINT(_L("TDrive::CheckMount() Not Mounted"));
 | 
|  |    218 |         const TInt KMaxMountFailures = 3;
 | 
|  |    219 | 		// if we've repeatedly failed to mount, give up until a media change
 | 
|  |    220 | 		if (iMountFailures >= KMaxMountFailures)
 | 
|  |    221 | 			{
 | 
|  |    222 | 			__PRINT1(_L("TDrive::CheckMount() retries exceeded, last Err:%d"), iLastMountError);
 | 
|  |    223 | 			return iLastMountError;
 | 
|  |    224 | 			}
 | 
|  |    225 | 
 | 
|  |    226 | 		if (!ReMount())	    //	Have we just remounted a mount we have previously encountered?
 | 
|  |    227 | 			{			
 | 
|  |    228 | 			MountFileSystem(EFalse);	//	If not, mount it for the first time now
 | 
|  |    229 | 			}
 | 
|  |    230 | 		else if(IsWriteProtected() && IsWriteableResource())
 | 
|  |    231 | 			{
 | 
|  |    232 | 			DoDismount();
 | 
|  |    233 | 			return KErrAccessDenied;
 | 
|  |    234 | 			}
 | 
|  |    235 | 		}
 | 
|  |    236 | 
 | 
|  |    237 | 	if (iReason==KErrNone && CurrentMount().LockStatus() > 0)
 | 
|  |    238 | 	    {
 | 
|  |    239 |     	//-- this meand that the mount has drive access objetcs opened (RFormat or RRawDisk)
 | 
|  |    240 |         __PRINT1(_L("TDrive::CheckMount() Mount is locked! LockStaus:%d"), CurrentMount().LockStatus());
 | 
|  |    241 |         return KErrInUse;
 | 
|  |    242 | 	    }	
 | 
|  |    243 | 
 | 
|  |    244 | 	__PRINT1(_L("TDrive::CheckMount returned %d "),iReason);
 | 
|  |    245 | 		
 | 
|  |    246 | 	return(iReason);
 | 
|  |    247 | 	}
 | 
|  |    248 | 
 | 
|  |    249 | //----------------------------------------------------------------------------
 | 
|  |    250 | /**
 | 
|  |    251 |     Try and re-mount any of the pending media
 | 
|  |    252 |     
 | 
|  |    253 |     @return ETrue if the mount matching media found and been attached back (set as iCurrentMount)
 | 
|  |    254 | */
 | 
|  |    255 | TBool TDrive::ReMount()
 | 
|  |    256 | 	{
 | 
|  |    257 | 	const TInt mCount=Mount().Count();
 | 
|  |    258 |     __PRINT1(_L("TDrive::ReMount() MountCnt:%d"), mCount);
 | 
|  |    259 | 	
 | 
|  |    260 | 	const TInt u=(Mount().UniqueID()<<16);
 | 
|  |    261 | 	iReason=KErrNone;
 | 
|  |    262 | 	
 | 
|  |    263 |     //-- try every instance of CMountCB that is associated with this object of TDrive.
 | 
|  |    264 |     //-- mounts are stored in the container of mCount elements.
 | 
|  |    265 |     //-- if some CMountCB recognises the media it belongs, it means that "remount succeded"
 | 
|  |    266 |     for(TInt i=0; i<mCount; i++)
 | 
|  |    267 | 		{
 | 
|  |    268 | 		CMountCB* pM=(CMountCB*)Mount().At(u|i);
 | 
|  |    269 | 		
 | 
|  |    270 |         if (ReMount(*pM))
 | 
|  |    271 | 			return ETrue;
 | 
|  |    272 | 		}
 | 
|  |    273 | 
 | 
|  |    274 | 	return EFalse;
 | 
|  |    275 | 	}
 | 
|  |    276 | 
 | 
|  |    277 | //----------------------------------------------------------------------------
 | 
|  |    278 | /**
 | 
|  |    279 |     Try and re-mount the specified media.
 | 
|  |    280 | 
 | 
|  |    281 |     @return ETrue if remounting succeeded - i.e. the CMountCB instance that matches the media is found in the 
 | 
|  |    282 |     mounts container (Mount()) and bound to the media.
 | 
|  |    283 | */
 | 
|  |    284 | TBool TDrive::ReMount(CMountCB& aMount)
 | 
|  |    285 | 	{
 | 
|  |    286 | 	__PRINT1(_L("TDrive::ReMount(0x%x)"), &aMount);
 | 
|  |    287 | 	iReason=KErrNone;
 | 
|  |    288 | 
 | 
|  |    289 | 	if (!aMount.IsDismounted() && !aMount.ProxyDriveDismounted())
 | 
|  |    290 | 		{
 | 
|  |    291 | 		aMount.SetDrive(this);
 | 
|  |    292 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMount, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    293 | 		
 | 
|  |    294 |         //-- actually, this is asking CMountCB to see if it belongs to the current media. 
 | 
|  |    295 |         iReason = aMount.ReMount();
 | 
|  |    296 | 
 | 
|  |    297 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMountRet, EF32TraceUidFileSys, iReason);
 | 
|  |    298 | 		
 | 
|  |    299 |         if (iReason == KErrNone)	//	ReMount succeeded
 | 
|  |    300 | 			{
 | 
|  |    301 | 			aMount.Open();
 | 
|  |    302 | 			iCurrentMount = &aMount;
 | 
|  |    303 | 			__PRINT1(_L("TDrive::ReMount for Mount:0x%x OK!"), &aMount);
 | 
|  |    304 | 			return ETrue;
 | 
|  |    305 | 			}
 | 
|  |    306 | 
 | 
|  |    307 | 		__PRINT2(_L("TDrive::ReMount for Mount:0x%x failed iReason=%d"),&aMount,iReason);
 | 
|  |    308 | 		}
 | 
|  |    309 | 	else
 | 
|  |    310 | 		{
 | 
|  |    311 | 		__PRINT1(_L("TDrive::ReMount() failed - Mount:0x%x is dismounted"), &aMount);
 | 
|  |    312 | 		}
 | 
|  |    313 | 
 | 
|  |    314 | 	return EFalse;
 | 
|  |    315 | 	}
 | 
|  |    316 | 
 | 
|  |    317 | 
 | 
|  |    318 | 
 | 
|  |    319 | //----------------------------------------------------------------------------
 | 
|  |    320 | /**
 | 
|  |    321 |     Mount the media on the drive. Optionally force a bad media to be mounted.
 | 
|  |    322 |     
 | 
|  |    323 |     @param  apMount     out: pointer to the produced CMountCB object; NULL if the CMountCB is not constructed
 | 
|  |    324 |     @param  aForceMount if ETrue, the filesystem will be forcedly mounted on the drive, disregarding what it contains. 
 | 
|  |    325 |     @param  aFsNameHash file system name hash; see TDrive::MountFileSystem()   
 | 
|  |    326 | */
 | 
|  |    327 | void TDrive::DoMountFileSystemL(CMountCB*& apMount, TBool aForceMount, TUint32 aFsNameHash)
 | 
|  |    328 | 	{
 | 
|  |    329 | 	CFileSystem* pMountsFs = NULL; //-- reference to the filesystem that will be producing CMountCB
 | 
|  |    330 |     
 | 
|  |    331 |     apMount = NULL;
 | 
|  |    332 | 
 | 
|  |    333 |     TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |    334 |    
 | 
|  |    335 |     //-- construct a new CmountCB object.
 | 
|  |    336 |     //-- on return pMountsFs will be the pointer to the factory object of CFileSystem that produced this mount
 | 
|  |    337 |     apMount = FSys().NewMountExL(this, &pMountsFs, aForceMount, aFsNameHash);
 | 
|  |    338 | 
 | 
|  |    339 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, KErrNone, apMount);
 | 
|  |    340 | 	__PRINT2(_L("TDrive::MountMediaL created mount:0x%x FileSys:0x%x"), apMount, pMountsFs);
 | 
|  |    341 | 
 | 
|  |    342 |     ASSERT(pMountsFs && apMount);
 | 
|  |    343 | 
 | 
|  |    344 | 	apMount->SetMountNumber(iMountNumber++);
 | 
|  |    345 |     apMount->InitL(*this, pMountsFs);  //-- initialise Mount
 | 
|  |    346 |     apMount->MountL(aForceMount);      //-- mount the file system  
 | 
|  |    347 | 	Mount().AddL(apMount,EFalse);      //-- add mount object to the mounts container.  
 | 
|  |    348 | 
 | 
|  |    349 | 	iCurrentMount=apMount;
 | 
|  |    350 |     }
 | 
|  |    351 | 
 | 
|  |    352 | 
 | 
|  |    353 | //----------------------------------------------------------------------------
 | 
|  |    354 | /*
 | 
|  |    355 | 	Mount file system on the drive. 
 | 
|  |    356 | 	@param  aForceMount if EFalse, will try to mount the file system normally, the file system implementation will decide if it can work on this drive or not.
 | 
|  |    357 |                         if ETrue, will mount the file suystem by force, this is used mostly for formatting unrecognisable media.
 | 
|  |    358 | 
 | 
|  |    359 |     @param  aFsNameHash optional parameter. Can specify the concrete file system name (hash). It can be used to force mounting  some specific
 | 
|  |    360 |                         file system. Default value '0' means "not specified / not used"
 | 
|  |    361 |                                                               
 | 
|  |    362 | 
 | 
|  |    363 |     TDrive::iReason on return contains the operation result code.
 | 
|  |    364 | */
 | 
|  |    365 | void TDrive::MountFileSystem(TBool aForceMount, TUint32 aFsNameHash /*=0*/ )
 | 
|  |    366 | 	{
 | 
|  |    367 | 	__PRINT2(_L("TDrive::MountFileSystem aForceMount=%d, FSNameHash:0x%x"),aForceMount, aFsNameHash);
 | 
|  |    368 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |    369 | 	
 | 
|  |    370 |     iCurrentMount=NULL;
 | 
|  |    371 | 	if(!iFSys)
 | 
|  |    372 | 		{
 | 
|  |    373 | 		iReason=KErrNotReady;
 | 
|  |    374 | 		return;
 | 
|  |    375 | 		}
 | 
|  |    376 | 	
 | 
|  |    377 |     CMountCB* pM=NULL;
 | 
|  |    378 |     TRAP(iReason, DoMountFileSystemL(pM, aForceMount, aFsNameHash));
 | 
|  |    379 | 	if (iReason == KErrNone)
 | 
|  |    380 | 		{
 | 
|  |    381 | 		iMountFailures = 0;
 | 
|  |    382 | 		ASSERT(iCurrentMount);
 | 
|  |    383 |         }
 | 
|  |    384 | 	else
 | 
|  |    385 | 		{
 | 
|  |    386 | 		iLastMountError = iReason;
 | 
|  |    387 | 		iMountFailures++;
 | 
|  |    388 | 		__PRINT2(_L("TDrive::MountFileSystem 0x%x failed iReason=%d"),pM,iReason);
 | 
|  |    389 | 		if(pM)
 | 
|  |    390 | 			pM->Close();
 | 
|  |    391 | 		
 | 
|  |    392 |         ASSERT(!iCurrentMount);
 | 
|  |    393 |         }
 | 
|  |    394 | 	}
 | 
|  |    395 | 
 | 
|  |    396 | 
 | 
|  |    397 | //----------------------------------------------------------------------------
 | 
|  |    398 | /**
 | 
|  |    399 |     Generic mount control method.
 | 
|  |    400 |     @param  aLevel  specifies the operation to perfrom on the mount
 | 
|  |    401 |     @param  aOption specific option for the given operation
 | 
|  |    402 |     @param  aParam  pointer to generic parameter, its meaning depends on aLevel and aOption
 | 
|  |    403 | 
 | 
|  |    404 |     @return standard error code.
 | 
|  |    405 | */
 | 
|  |    406 | TInt TDrive::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
 | 
|  |    407 |     {
 | 
|  |    408 | 	TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControl, EF32TraceUidFileSys, DriveNumber(), aLevel, aOption, aParam);
 | 
|  |    409 |     TInt r = CurrentMount().MountControl(aLevel, aOption, aParam);
 | 
|  |    410 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControlRet, EF32TraceUidFileSys, r);
 | 
|  |    411 | 
 | 
|  |    412 | 	return r;
 | 
|  |    413 |     }
 | 
|  |    414 | 
 | 
|  |    415 | //----------------------------------------------------------------------------
 | 
|  |    416 | /**
 | 
|  |    417 |     Request aFreeSpaceRequired free bytes from the mount associated with this drive.
 | 
|  |    418 |     The volume free space on for some filesystems can be changing (usually increasing) after it has been mounted.
 | 
|  |    419 |     If the mount supports this functionality, it can block this call until certain number of free bytes encounted if its free
 | 
|  |    420 |     space calculation activity hasn't finished yet.
 | 
|  |    421 | 
 | 
|  |    422 |     @param  aFreeSpaceRequired  required free space, bytes.
 | 
|  |    423 |     
 | 
|  |    424 |     @return KErrNone        on success and if there is at least aFreeSpaceRequired bytes on the volume
 | 
|  |    425 |             KErrDiskFull    on success and if there is no aFreeSpaceRequired bytes on the volume
 | 
|  |    426 |             system-wide error code otherwise
 | 
|  |    427 | */
 | 
|  |    428 | TInt TDrive::RequestFreeSpaceOnMount(TUint64 aFreeSpaceRequired)
 | 
|  |    429 |     {
 | 
|  |    430 |     TInt nRes;
 | 
|  |    431 | 
 | 
|  |    432 |     nRes = CheckMount();
 | 
|  |    433 |     if(nRes != KErrNone)
 | 
|  |    434 |         return nRes;
 | 
|  |    435 | 
 | 
|  |    436 |     //-- 1. Try mount-specific request first. If the mount is still performing free space calculations,
 | 
|  |    437 |     //-- the caller will be suspended until aFreeSpaceRequired bytes is available or scanning process finishes
 | 
|  |    438 |     {
 | 
|  |    439 |         TUint64 freeSpaceReq = aFreeSpaceRequired;
 | 
|  |    440 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpace, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    441 |         nRes = CurrentMount().RequestFreeSpace(freeSpaceReq);
 | 
|  |    442 | 		TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(freeSpaceReq), I64HIGH(freeSpaceReq));
 | 
|  |    443 |         if(nRes == KErrNone)
 | 
|  |    444 |             {
 | 
|  |    445 |             return (freeSpaceReq >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
 | 
|  |    446 |             }
 | 
|  |    447 |     }
 | 
|  |    448 | 
 | 
|  |    449 |     //-- given Mount doesn't support this functionality, use legacy method
 | 
|  |    450 |     TVolumeInfo volInfo;
 | 
|  |    451 |     nRes = Volume(volInfo);
 | 
|  |    452 |     if(nRes !=KErrNone)
 | 
|  |    453 |         return nRes;
 | 
|  |    454 | 
 | 
|  |    455 |     return ((TUint64)volInfo.iFree >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
 | 
|  |    456 |     }
 | 
|  |    457 | 
 | 
|  |    458 | //----------------------------------------------------------------------------
 | 
|  |    459 | /**
 | 
|  |    460 |     Get size of the mounted volume. It can be less than physical volume size because FileSystem data may occupy some space.
 | 
|  |    461 |     
 | 
|  |    462 |     @param  aSize on success mounted volume size in bytes will be returned there
 | 
|  |    463 |     @return KErrNone on success, standard error code otherwise
 | 
|  |    464 | */
 | 
|  |    465 | TInt TDrive::MountedVolumeSize(TUint64& aSize)
 | 
|  |    466 |     {
 | 
|  |    467 |     TInt nRes;
 | 
|  |    468 | 
 | 
|  |    469 |     nRes = CheckMount();
 | 
|  |    470 |     if(nRes != KErrNone)
 | 
|  |    471 |         return nRes;
 | 
|  |    472 | 
 | 
|  |    473 |     //-- 1. Try mount-specific request first. It won't block this call as CMountCB::VolumeL() can do if some background activity is going on the mount
 | 
|  |    474 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    475 |     nRes = CurrentMount().MountedVolumeSize(aSize);
 | 
|  |    476 | 	TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, nRes, I64LOW(aSize), I64HIGH(aSize));
 | 
|  |    477 |     if(nRes == KErrNone)
 | 
|  |    478 |         return nRes;
 | 
|  |    479 | 
 | 
|  |    480 |     //-- given Mount doesn't support this functionality, use legacy method
 | 
|  |    481 |     TVolumeInfo volInfo;
 | 
|  |    482 |     nRes = Volume(volInfo);
 | 
|  |    483 |     if(nRes == KErrNone)
 | 
|  |    484 |         {
 | 
|  |    485 |         aSize = volInfo.iSize;
 | 
|  |    486 |         }
 | 
|  |    487 |     
 | 
|  |    488 |     return nRes;
 | 
|  |    489 |     }
 | 
|  |    490 | 
 | 
|  |    491 | //----------------------------------------------------------------------------
 | 
|  |    492 | /**
 | 
|  |    493 |     Get _current_ amount of free space on the volume. Some mounts implementations can be updating the amount of free space
 | 
|  |    494 |     in background. 
 | 
|  |    495 | 
 | 
|  |    496 |     @param  aFreeDiskSpace on success will contain a current amount of free space
 | 
|  |    497 |     @return KErrNone on success, standard error code otherwise
 | 
|  |    498 | 
 | 
|  |    499 | */
 | 
|  |    500 | TInt TDrive::FreeDiskSpace(TInt64& aFreeDiskSpace)
 | 
|  |    501 | 	{
 | 
|  |    502 |     TInt nRes;
 | 
|  |    503 | 
 | 
|  |    504 |     nRes = CheckMount();
 | 
|  |    505 |     if(nRes != KErrNone)
 | 
|  |    506 |         return nRes;
 | 
|  |    507 | 
 | 
|  |    508 |     //-- 1. Try mount-specific request first. It won't block this call as CMountCB::VolumeL() can do 
 | 
|  |    509 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpace, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    510 |     nRes = CurrentMount().GetCurrentFreeSpaceAvailable(aFreeDiskSpace);
 | 
|  |    511 | 	TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(aFreeDiskSpace), I64HIGH(aFreeDiskSpace));
 | 
|  |    512 |     if(nRes == KErrNone)
 | 
|  |    513 |         return nRes;
 | 
|  |    514 | 
 | 
|  |    515 |     //-- given Mount doesn't support this functionality, use legacy method
 | 
|  |    516 |     TVolumeInfo volInfo;
 | 
|  |    517 |     nRes = Volume(volInfo);
 | 
|  |    518 |     if(nRes == KErrNone)
 | 
|  |    519 |         {
 | 
|  |    520 |         aFreeDiskSpace = volInfo.iFree;
 | 
|  |    521 |         }
 | 
|  |    522 |     
 | 
|  |    523 |     return nRes;
 | 
|  |    524 | 	}
 | 
|  |    525 | 
 | 
|  |    526 | //----------------------------------------------------------------------------
 | 
|  |    527 | /**
 | 
|  |    528 |     Finalise drive (the mount).
 | 
|  |    529 | 
 | 
|  |    530 |     @param  aOperation  describes finalisation operation ,see RFs::TFinaliseDrvMode
 | 
|  |    531 |     @param  aParam1     not used, for future expansion
 | 
|  |    532 |     @param  aParam2     not used, for future expansion
 | 
|  |    533 | 
 | 
|  |    534 |     @return Standard error code
 | 
|  |    535 | */
 | 
|  |    536 | TInt TDrive::FinaliseMount(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
 | 
|  |    537 | 	{
 | 
|  |    538 | 	TInt r=CheckMount();
 | 
|  |    539 | 	if (r!=KErrNone)
 | 
|  |    540 | 		return(r);
 | 
|  |    541 | 
 | 
|  |    542 | 	r = FlushCachedFileInfo();
 | 
|  |    543 | 	if (r!=KErrNone)
 | 
|  |    544 | 		return(r);
 | 
|  |    545 | 
 | 
|  |    546 | 	if(IsWriteProtected())
 | 
|  |    547 | 		return(KErrAccessDenied);
 | 
|  |    548 | 
 | 
|  |    549 | 	TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
 | 
|  |    550 | 	TRAP(r,CurrentMount().FinaliseMountL(aOperation, aParam1, aParam2));
 | 
|  |    551 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2Ret, EF32TraceUidFileSys, r);
 | 
|  |    552 | 	
 | 
|  |    553 |     return r;
 | 
|  |    554 | 	}
 | 
|  |    555 | 
 | 
|  |    556 | //----------------------------------------------------------------------------
 | 
|  |    557 | /** old implementation */
 | 
|  |    558 | TInt TDrive::FinaliseMount()
 | 
|  |    559 | 	{
 | 
|  |    560 | 	TInt r=CheckMount();
 | 
|  |    561 | 	if (r!=KErrNone)
 | 
|  |    562 | 		return(r);
 | 
|  |    563 | 
 | 
|  |    564 | 	r = FlushCachedFileInfo();
 | 
|  |    565 | 	if (r!=KErrNone)
 | 
|  |    566 | 		return(r);
 | 
|  |    567 | 
 | 
|  |    568 | 	if(IsWriteProtected())
 | 
|  |    569 | 		return(KErrAccessDenied);
 | 
|  |    570 | 
 | 
|  |    571 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    572 | 	TRAP(r,CurrentMount().FinaliseMountL());
 | 
|  |    573 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1Ret, EF32TraceUidFileSys, r);
 | 
|  |    574 | 	
 | 
|  |    575 |     return r;
 | 
|  |    576 | 	}
 | 
|  |    577 | 
 | 
|  |    578 | 
 | 
|  |    579 | 
 | 
|  |    580 | CFileCB* TDrive::LocateFile(const TDesC& aName)
 | 
|  |    581 | //
 | 
|  |    582 | //	Locate a file of the same name already open on the drive.
 | 
|  |    583 | //
 | 
|  |    584 | 	{
 | 
|  |    585 | 	TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
 | 
|  |    586 | 	CFileCB* pF;
 | 
|  |    587 | 	// early out for normal case, list is empty
 | 
|  |    588 | 	if(q==NULL)
 | 
|  |    589 | 		return NULL;
 | 
|  |    590 | 	
 | 
|  |    591 | 	// strip off trailing dots
 | 
|  |    592 | 	TInt length= aName.Length();
 | 
|  |    593 | 	while((length !=0) && (aName[length-1]==KExtDelimiter))
 | 
|  |    594 | 		{
 | 
|  |    595 | 		length--;
 | 
|  |    596 | 		}
 | 
|  |    597 | 
 | 
|  |    598 | 	TPtrC temp(aName.Ptr(),length);
 | 
|  |    599 | 
 | 
|  |    600 | 	TFileName tempName;
 | 
|  |    601 | 	tempName.CopyF(temp);
 | 
|  |    602 | 	TUint32 nameHash=CalcNameHash(tempName);
 | 
|  |    603 | 
 | 
|  |    604 | 	while ((pF=q++)!=NULL)
 | 
|  |    605 | 		{
 | 
|  |    606 | 		if(nameHash==pF->NameHash())
 | 
|  |    607 | 			{
 | 
|  |    608 | 			if (pF->FileNameF().Match(tempName)==KErrNone)
 | 
|  |    609 | 				return(pF);
 | 
|  |    610 | 			}	
 | 
|  |    611 | 		}
 | 
|  |    612 | 	return(NULL);
 | 
|  |    613 | 	}
 | 
|  |    614 | 
 | 
|  |    615 | 
 | 
|  |    616 | CFileCache* TDrive::LocateClosedFile(const TDesC& aName, TBool aResurrect)
 | 
|  |    617 | //
 | 
|  |    618 | //	Locate a recently closed file of the same name on the drive.
 | 
|  |    619 | //
 | 
|  |    620 | 	{
 | 
|  |    621 | 	// strip off trailing dots
 | 
|  |    622 | 	TInt length= aName.Length();
 | 
|  |    623 | 	while((length !=0) && (aName[length-1]==KExtDelimiter))
 | 
|  |    624 | 		{
 | 
|  |    625 | 		length--;
 | 
|  |    626 | 		}
 | 
|  |    627 | 
 | 
|  |    628 | 	TPtrC temp(aName.Ptr(),length);
 | 
|  |    629 | 
 | 
|  |    630 | 	TFileName tempName;
 | 
|  |    631 | 	tempName.CopyF(temp);
 | 
|  |    632 | 	TUint32 nameHash=CalcNameHash(tempName);
 | 
|  |    633 | 
 | 
|  |    634 | 	CFileCache* pF = NULL;
 | 
|  |    635 | 	CMountCB* currentMount = &CurrentMount();
 | 
|  |    636 | 
 | 
|  |    637 | 
 | 
|  |    638 | 	TClosedFileUtils::Lock();
 | 
|  |    639 | 
 | 
|  |    640 | 	TInt count = TClosedFileUtils::Count();
 | 
|  |    641 | 	while(count--)
 | 
|  |    642 | 		{
 | 
|  |    643 | 		CFileCache* fileCache = TClosedFileUtils::At(count);
 | 
|  |    644 | 		if (&fileCache->Drive() == this &&
 | 
|  |    645 | 			fileCache->NameHash()== nameHash && 
 | 
|  |    646 | 			fileCache->FileNameF().Match(tempName)==KErrNone &&
 | 
|  |    647 | 			&fileCache->Mount() == currentMount)
 | 
|  |    648 | 			{
 | 
|  |    649 | 			__ASSERT_DEBUG(TClosedFileUtils::IsClosed(fileCache), Fault(EObjRemoveContainerNotFound));
 | 
|  |    650 | 			__CACHE_PRINT2(_L("CLOSEDFILES: LocateClosedFile(%S, %d\n"), &fileCache->FileNameF(), aResurrect);
 | 
|  |    651 | 			if (aResurrect)
 | 
|  |    652 | 				{
 | 
|  |    653 | 				TClosedFileUtils::ReOpen(fileCache, EFalse);
 | 
|  |    654 | 				}
 | 
|  |    655 | 			pF = fileCache;
 | 
|  |    656 | 			break;
 | 
|  |    657 | 			}
 | 
|  |    658 | 
 | 
|  |    659 | 		}
 | 
|  |    660 | 	TClosedFileUtils::Unlock();
 | 
|  |    661 | 
 | 
|  |    662 | 	if (pF != NULL && !aResurrect)
 | 
|  |    663 | 		{
 | 
|  |    664 | 		pF->Close();
 | 
|  |    665 | 		pF = NULL;
 | 
|  |    666 | 		}
 | 
|  |    667 | 
 | 
|  |    668 | 	return(pF);
 | 
|  |    669 | 	}
 | 
|  |    670 | 
 | 
|  |    671 | 
 | 
|  |    672 | static TBool IsSubDir(const TDesC& aFullName,const TDesC& aParent)
 | 
|  |    673 | //
 | 
|  |    674 | // Returns ETrue if aFullName is a subdirectory of aParent
 | 
|  |    675 | // Assumes aParent is a path name with the trailing backslash removed
 | 
|  |    676 | //
 | 
|  |    677 | 	{
 | 
|  |    678 | 
 | 
|  |    679 | 	__ASSERT_DEBUG(aParent.Length() && aParent[aParent.Length()-1]!=KPathDelimiter,Fault(EIsSubDirBadDes));
 | 
|  |    680 | 	TPtrC entryFullName(NULL,0);
 | 
|  |    681 | 	TPtrC entryParent(NULL,0);
 | 
|  |    682 | 	TInt posFullName=0;
 | 
|  |    683 | 	TInt posParent=0;
 | 
|  |    684 | 
 | 
|  |    685 | 	FOREVER
 | 
|  |    686 | 		{
 | 
|  |    687 | 		NextInPath(aParent,entryParent,posParent);
 | 
|  |    688 | 		if (entryParent.Length()==0)
 | 
|  |    689 | 			break;
 | 
|  |    690 | 		NextInPath(aFullName,entryFullName,posFullName);
 | 
|  |    691 | 		if (entryParent!=entryFullName)
 | 
|  |    692 | 			return(EFalse);
 | 
|  |    693 | 		}
 | 
|  |    694 | 
 | 
|  |    695 | 	if (aFullName.Length()<=posFullName)
 | 
|  |    696 | 		return(EFalse);
 | 
|  |    697 | 	if (aFullName[posFullName]!=KPathDelimiter)
 | 
|  |    698 | 		return(EFalse);
 | 
|  |    699 | 	return(ETrue);
 | 
|  |    700 | 	}
 | 
|  |    701 | 
 | 
|  |    702 | CFileCB* TDrive::LocateFileByPath(const TDesC& aPath)
 | 
|  |    703 | //
 | 
|  |    704 | // Locate a file opened in a subdirectory of aPath
 | 
|  |    705 | //
 | 
|  |    706 | 	{
 | 
|  |    707 | 
 | 
|  |    708 | 	TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
 | 
|  |    709 | 	CFileCB* pF;
 | 
|  |    710 | 	while ((pF=q++)!=NULL)
 | 
|  |    711 | 		{
 | 
|  |    712 | 		if (IsSubDir(pF->FileName(),aPath))
 | 
|  |    713 | 			return(pF);
 | 
|  |    714 | 		}
 | 
|  |    715 | 	return(NULL);
 | 
|  |    716 | 	}
 | 
|  |    717 | 
 | 
|  |    718 | void TDrive::FlushCachedFileInfoL()
 | 
|  |    719 | //
 | 
|  |    720 | // Flush data stored in the file control blocks
 | 
|  |    721 | //
 | 
|  |    722 | 	{
 | 
|  |    723 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |    724 | 	TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
 | 
|  |    725 | 	CFileCB* pF;
 | 
|  |    726 | 	while ((pF=q++)!=NULL)
 | 
|  |    727 | 		{
 | 
|  |    728 | 		if (pF->iAtt&KEntryAttModified)
 | 
|  |    729 | 			pF->FlushAllL();
 | 
|  |    730 | 		}
 | 
|  |    731 | 	}
 | 
|  |    732 | 
 | 
|  |    733 | /**
 | 
|  |    734 | Flushes (asynchronously) all dirty data on this drive and optionally
 | 
|  |    735 | purges non-dirty data
 | 
|  |    736 | 
 | 
|  |    737 | aPurgeCache - purges all file caches on this drive AFTER dirty data has ben flushed 
 | 
|  |    738 | 
 | 
|  |    739 | returns KErrNone if complete
 | 
|  |    740 | 		CFsRequest::EReqActionBusy if flushing is in progress
 | 
|  |    741 | 		otherwise one of the other system-wide error codes.
 | 
|  |    742 | */
 | 
|  |    743 | TInt TDrive::FlushCachedFileInfo(TBool aPurgeCache)
 | 
|  |    744 | 	{
 | 
|  |    745 | 	if (iCurrentMount == NULL)
 | 
|  |    746 | 		return KErrNone;
 | 
|  |    747 | 
 | 
|  |    748 | 	TBool driveThread = FsThreadManager::IsDriveThread(iDriveNumber,EFalse);
 | 
|  |    749 | 
 | 
|  |    750 | 	Lock();
 | 
|  |    751 | 	
 | 
|  |    752 | 
 | 
|  |    753 | 	TInt ret = KErrNone;
 | 
|  |    754 | 
 | 
|  |    755 | 	TDblQueIter<CFileCB> q(iCurrentMount->iMountQ);
 | 
|  |    756 | 	CFileCB* pF;
 | 
|  |    757 | 	while ((pF=q++)!=NULL)
 | 
|  |    758 | 		{
 | 
|  |    759 | 		CFileCache* fileCache = pF->FileCache();
 | 
|  |    760 | 
 | 
|  |    761 | 		// Write dirty data if there is a file cache
 | 
|  |    762 | 		TInt flushDirtyRetCode = CFsRequest::EReqActionComplete;
 | 
|  |    763 | 		if (fileCache)
 | 
|  |    764 | 			{
 | 
|  |    765 | 			flushDirtyRetCode = fileCache->FlushDirty();
 | 
|  |    766 | 			if (flushDirtyRetCode == CFsRequest::EReqActionComplete)	// nothing to flush
 | 
|  |    767 | 				{
 | 
|  |    768 | 				if (aPurgeCache)
 | 
|  |    769 | 					fileCache->Purge(EFalse);
 | 
|  |    770 | 				}
 | 
|  |    771 | 			else if (flushDirtyRetCode == CFsRequest::EReqActionBusy)	// flushing
 | 
|  |    772 | 				{
 | 
|  |    773 | 				ret = flushDirtyRetCode;
 | 
|  |    774 | 				}
 | 
|  |    775 | 			else	// error
 | 
|  |    776 | 				{
 | 
|  |    777 | 				ret = flushDirtyRetCode;
 | 
|  |    778 | 				break;
 | 
|  |    779 | 				}
 | 
|  |    780 | 			}
 | 
|  |    781 | 		// if no file cache or no dirty data left, update the file entry & attributes
 | 
|  |    782 | 		if (driveThread && (pF->iAtt&KEntryAttModified) && flushDirtyRetCode == CFsRequest::EReqActionComplete )
 | 
|  |    783 | 			{
 | 
|  |    784 | 			TRAP(ret, pF->FlushAllL());
 | 
|  |    785 | 			if (ret != KErrNone)
 | 
|  |    786 | 				break;
 | 
|  |    787 | 			}
 | 
|  |    788 | 		}
 | 
|  |    789 | 
 | 
|  |    790 | 	UnLock();
 | 
|  |    791 | 
 | 
|  |    792 | 
 | 
|  |    793 | 	return ret;
 | 
|  |    794 | 	}
 | 
|  |    795 | 
 | 
|  |    796 | //----------------------------------------------------------------------------
 | 
|  |    797 | /**
 | 
|  |    798 |     Purge dirty cache data associated with all files on a given mount
 | 
|  |    799 | */
 | 
|  |    800 | void TDrive::PurgeDirty(CMountCB& aMount)
 | 
|  |    801 | 	{
 | 
|  |    802 | 	TDblQueIter<CFileCB> q(aMount.iMountQ);
 | 
|  |    803 | 	CFileCB* pF;
 | 
|  |    804 | 	while ((pF=q++)!=NULL)
 | 
|  |    805 | 		{
 | 
|  |    806 | 		CFileCache* fileCache = pF->FileCache();
 | 
|  |    807 | 		if (fileCache)
 | 
|  |    808 | 		    {
 | 
|  |    809 |         	fileCache->Purge(ETrue);
 | 
|  |    810 |             fileCache->MarkFileClean();
 | 
|  |    811 |             }
 | 
|  |    812 | 		}
 | 
|  |    813 | 	}
 | 
|  |    814 | 
 | 
|  |    815 | //----------------------------------------------------------------------------
 | 
|  |    816 | TInt TDrive::ValidateShare(CFileCB& aFile, TShare aReqShare)
 | 
|  |    817 | //
 | 
|  |    818 | // Check that the sharing rules are obeyed.
 | 
|  |    819 | //
 | 
|  |    820 | 	{
 | 
|  |    821 | 
 | 
|  |    822 | 	switch (aReqShare)
 | 
|  |    823 | 		{
 | 
|  |    824 | 	case EFileShareExclusive:
 | 
|  |    825 | 	case EFileShareReadersOnly:
 | 
|  |    826 | 	case EFileShareAny:
 | 
|  |    827 | 	case EFileShareReadersOrWriters:
 | 
|  |    828 | 		break;
 | 
|  |    829 | 	default:
 | 
|  |    830 | 		return(KErrArgument);
 | 
|  |    831 | 		}
 | 
|  |    832 | 	switch (aFile.iShare)
 | 
|  |    833 | 		{
 | 
|  |    834 | 	case EFileShareExclusive:
 | 
|  |    835 | 		return(KErrInUse);
 | 
|  |    836 | 
 | 
|  |    837 | 	case EFileShareReadersOnly:
 | 
|  |    838 | 	case EFileShareAny:
 | 
|  |    839 | 		if (aReqShare != aFile.iShare && aReqShare != EFileShareReadersOrWriters)
 | 
|  |    840 | 			return(KErrInUse);
 | 
|  |    841 | 		break;
 | 
|  |    842 | 
 | 
|  |    843 | 	case EFileShareReadersOrWriters:
 | 
|  |    844 | 		if (aReqShare==EFileShareExclusive)
 | 
|  |    845 | 			return(KErrInUse);
 | 
|  |    846 | 		//
 | 
|  |    847 | 		// If the file is currently open as EFileShareReadersOrWriters then
 | 
|  |    848 | 		// promote the share to the requested share mode.
 | 
|  |    849 | 		//
 | 
|  |    850 | 		// If the requested share is EFileShareReadersOnly, verfiy that no
 | 
|  |    851 | 		// other share has the file open for writing.
 | 
|  |    852 | 		//
 | 
|  |    853 | 
 | 
|  |    854 | 		if (aReqShare == EFileShareReadersOnly)
 | 
|  |    855 | 			{
 | 
|  |    856 | 			FileShares->Lock();
 | 
|  |    857 | 			TInt count = FileShares->Count();
 | 
|  |    858 | 			while(count--)
 | 
|  |    859 | 				{
 | 
|  |    860 | 				CFileShare* share = (CFileShare*)(*FileShares)[count];
 | 
|  |    861 | 				if (&share->File() == &aFile)
 | 
|  |    862 | 					{
 | 
|  |    863 | 					if(share->iMode & EFileWrite)
 | 
|  |    864 | 						{
 | 
|  |    865 | 						FileShares->Unlock();
 | 
|  |    866 | 						return KErrInUse;
 | 
|  |    867 | 						}
 | 
|  |    868 | 					}
 | 
|  |    869 | 				}
 | 
|  |    870 | 			FileShares->Unlock();
 | 
|  |    871 | 			}
 | 
|  |    872 | 		break;
 | 
|  |    873 |     
 | 
|  |    874 | 	default:
 | 
|  |    875 | 		Fault(EDrvIllegalShareValue);
 | 
|  |    876 |         break;
 | 
|  |    877 | 		}
 | 
|  |    878 | 	return(KErrNone);
 | 
|  |    879 | 	}
 | 
|  |    880 | 
 | 
|  |    881 | void TDrive::DriveInfo(TDriveInfo& anInfo)
 | 
|  |    882 | //
 | 
|  |    883 | // Get the drive info.
 | 
|  |    884 | //
 | 
|  |    885 | 	{
 | 
|  |    886 | 	anInfo.iType=EMediaNotPresent;
 | 
|  |    887 | 	anInfo.iMediaAtt=0;
 | 
|  |    888 | 
 | 
|  |    889 | 	TInt batStatus=HAL::EPowerBatteryStatus_Zero;
 | 
|  |    890 | 	TInt r=HAL::Get(HAL::EPowerBatteryStatus, batStatus);
 | 
|  |    891 | 	if (r==KErrNone)
 | 
|  |    892 | 		{
 | 
|  |    893 | 		switch(batStatus)
 | 
|  |    894 | 			{
 | 
|  |    895 | 		case HAL::EPowerBatteryStatus_Zero:
 | 
|  |    896 | 			anInfo.iBattery=EBatLow;
 | 
|  |    897 | 			break;
 | 
|  |    898 | 		case HAL::EPowerBatteryStatus_Replace:
 | 
|  |    899 | 			anInfo.iBattery=EBatLow;
 | 
|  |    900 | 			break;
 | 
|  |    901 | 		case HAL::EPowerBatteryStatus_Low:
 | 
|  |    902 | 			anInfo.iBattery=EBatLow;
 | 
|  |    903 | 			break;
 | 
|  |    904 | 		case HAL::EPowerBatteryStatus_Good:
 | 
|  |    905 | 			anInfo.iBattery=EBatGood;
 | 
|  |    906 | 			break;
 | 
|  |    907 | 			}		
 | 
|  |    908 | 		}
 | 
|  |    909 | 	else
 | 
|  |    910 | 		anInfo.iBattery=EBatNotSupported;
 | 
|  |    911 | 
 | 
|  |    912 | 	if(iFSys)
 | 
|  |    913 | 		{
 | 
|  |    914 | 		TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfo, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |    915 | 		FSys().DriveInfo(anInfo,DriveNumber());
 | 
|  |    916 | 		TRACE3(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfoRet, EF32TraceUidFileSys, 
 | 
|  |    917 | 			anInfo.iType, anInfo.iDriveAtt, anInfo.iMediaAtt);
 | 
|  |    918 | 		}
 | 
|  |    919 | 
 | 
|  |    920 | 	anInfo.iDriveAtt=Att();
 | 
|  |    921 | 	}
 | 
|  |    922 | 
 | 
|  |    923 | TInt TDrive::Volume(TVolumeInfo& aVolume)
 | 
|  |    924 | //
 | 
|  |    925 | // Get the drive volume info.
 | 
|  |    926 | //
 | 
|  |    927 | 	{
 | 
|  |    928 | 	TInt r=CheckMount();
 | 
|  |    929 | 	if (r==KErrNone)
 | 
|  |    930 | 		{
 | 
|  |    931 | 		DriveInfo(aVolume.iDrive);
 | 
|  |    932 | 		CMountCB& m=CurrentMount();
 | 
|  |    933 | 		aVolume.iName=m.VolumeName();
 | 
|  |    934 | 		aVolume.iUniqueID=m.iUniqueID;
 | 
|  |    935 | 		aVolume.iSize=m.iSize;
 | 
|  |    936 | 
 | 
|  |    937 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeL, EF32TraceUidFileSys, DriveNumber());
 | 
|  |    938 | 		TRAP(r,m.VolumeL(aVolume))
 | 
|  |    939 | 		TRACE7(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeLRet, EF32TraceUidFileSys, 
 | 
|  |    940 | 			r, aVolume.iUniqueID, I64LOW(aVolume.iSize), I64HIGH(aVolume.iSize),
 | 
|  |    941 | 			I64LOW(aVolume.iFree), I64HIGH(aVolume.iFree), aVolume.iFileCacheFlags);
 | 
|  |    942 | 
 | 
|  |    943 | 		}
 | 
|  |    944 | 	return(r);
 | 
|  |    945 | 	}
 | 
|  |    946 | 
 | 
|  |    947 | 
 | 
|  |    948 | void TDrive::SetVolumeL(const TDesC& aName,HBufC*& aBuf)
 | 
|  |    949 | //
 | 
|  |    950 | // Set the volume name.
 | 
|  |    951 | //
 | 
|  |    952 | 	{
 | 
|  |    953 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |    954 | 	aBuf=aName.AllocL();
 | 
|  |    955 | 	TPtr volumeName=aBuf->Des();
 | 
|  |    956 | 
 | 
|  |    957 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeL, EF32TraceUidFileSys, DriveNumber(), aName);
 | 
|  |    958 | 	CurrentMount().SetVolumeL(volumeName);
 | 
|  |    959 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeLRet, EF32TraceUidFileSys, KErrNone);
 | 
|  |    960 | 
 | 
|  |    961 | 
 | 
|  |    962 | 	delete &CurrentMount().VolumeName();
 | 
|  |    963 | 	CurrentMount().SetVolumeName(aBuf);
 | 
|  |    964 | 	}
 | 
|  |    965 | 
 | 
|  |    966 | TInt TDrive::SetVolume(const TDesC& aName)
 | 
|  |    967 | //
 | 
|  |    968 | // Set the volume name.
 | 
|  |    969 | //
 | 
|  |    970 | 	{
 | 
|  |    971 | 	TInt r=CheckMount();
 | 
|  |    972 | 	HBufC* pV=NULL;
 | 
|  |    973 | 	if (r==KErrNone)
 | 
|  |    974 | 		{
 | 
|  |    975 | 		if(IsWriteProtected())
 | 
|  |    976 | 			return(KErrAccessDenied);
 | 
|  |    977 | 		TRAP(r,SetVolumeL(aName,pV))
 | 
|  |    978 | 		if (r!=KErrNone)
 | 
|  |    979 | 			delete pV;
 | 
|  |    980 | 		}
 | 
|  |    981 | 	return(r);
 | 
|  |    982 | 	}
 | 
|  |    983 | 
 | 
|  |    984 | TInt TDrive::MkDir(const TDesC& aName)
 | 
|  |    985 | //
 | 
|  |    986 | // Make a directory.
 | 
|  |    987 | //
 | 
|  |    988 | 	{
 | 
|  |    989 | 	TInt r=CheckMount();
 | 
|  |    990 | 	if (r!=KErrNone)
 | 
|  |    991 | 		return(r);
 | 
|  |    992 | 	if(IsWriteProtected())
 | 
|  |    993 | 		return(KErrAccessDenied);
 | 
|  |    994 | 	TParse newDirName;
 | 
|  |    995 | 	newDirName.Set(aName,NULL,NULL);
 | 
|  |    996 | 
 | 
|  |    997 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirL, EF32TraceUidFileSys, DriveNumber(), aName);
 | 
|  |    998 | 	TRAP(r,CurrentMount().MkDirL(newDirName.FullName()))
 | 
|  |    999 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirLRet, EF32TraceUidFileSys, r);
 | 
|  |   1000 | 
 | 
|  |   1001 | 	return(r);
 | 
|  |   1002 | 	}
 | 
|  |   1003 | 
 | 
|  |   1004 | TInt TDrive::RmDir(const TDesC& aName)
 | 
|  |   1005 | //
 | 
|  |   1006 | // Remove a directory.
 | 
|  |   1007 | //
 | 
|  |   1008 | 	{
 | 
|  |   1009 | 	TInt r=CheckMount();
 | 
|  |   1010 | 	if (r!=KErrNone)
 | 
|  |   1011 | 		return(r);
 | 
|  |   1012 | 	TEntry entry;
 | 
|  |   1013 | 	r=Entry(aName,entry);
 | 
|  |   1014 | 	if (r!=KErrNone)
 | 
|  |   1015 | 		return(r);
 | 
|  |   1016 | 	if (entry.IsDir()==EFalse)
 | 
|  |   1017 | 		return(KErrPathNotFound);
 | 
|  |   1018 | 	if ((entry.iAtt&KEntryAttReadOnly) || IsWriteProtected())
 | 
|  |   1019 | 		return(KErrAccessDenied);
 | 
|  |   1020 | 
 | 
|  |   1021 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirL, EF32TraceUidFileSys, DriveNumber(), aName);
 | 
|  |   1022 | 	TRAP(r,CurrentMount().RmDirL(aName))
 | 
|  |   1023 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirLRet, EF32TraceUidFileSys, r);
 | 
|  |   1024 | 
 | 
|  |   1025 | 	return(r);
 | 
|  |   1026 | 	}
 | 
|  |   1027 | 
 | 
|  |   1028 | TInt TDrive::Delete(const TDesC& aName)
 | 
|  |   1029 | //
 | 
|  |   1030 | // Delete files allowing wild cards.
 | 
|  |   1031 | //
 | 
|  |   1032 | 	{
 | 
|  |   1033 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1034 | 	if (r!=KErrNone)
 | 
|  |   1035 | 		return(r);
 | 
|  |   1036 | 	CFileCB* pF=LocateFile(aName);
 | 
|  |   1037 | 	if (pF!=NULL)
 | 
|  |   1038 | 		return(KErrInUse);		
 | 
|  |   1039 | 
 | 
|  |   1040 | 	// remove from closed queue - NB this isn't strictly necessary if file is read-only or write-protected...
 | 
|  |   1041 | 	LocateClosedFile(aName, EFalse);
 | 
|  |   1042 | 
 | 
|  |   1043 | 	TEntry entry;
 | 
|  |   1044 | 	r=Entry(aName,entry);
 | 
|  |   1045 | 	if (r!=KErrNone)
 | 
|  |   1046 | 		return(r);
 | 
|  |   1047 | 	if (entry.IsDir() || IsWriteProtected() || entry.IsReadOnly())
 | 
|  |   1048 | 		return(KErrAccessDenied);
 | 
|  |   1049 | 
 | 
|  |   1050 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteL, EF32TraceUidFileSys, DriveNumber(), aName);
 | 
|  |   1051 | 	TRAP(r,CurrentMount().DeleteL(aName))
 | 
|  |   1052 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteLRet, EF32TraceUidFileSys, r);
 | 
|  |   1053 | 
 | 
|  |   1054 | 	return(r);
 | 
|  |   1055 | 	}
 | 
|  |   1056 | 
 | 
|  |   1057 | TInt TDrive::CheckMountAndEntryNames(const TDesC& anOldName,const TDesC& aNewName)
 | 
|  |   1058 | //
 | 
|  |   1059 | // Check mount, that neither is open, and that both names are legal.
 | 
|  |   1060 | //
 | 
|  |   1061 | 	{
 | 
|  |   1062 | 
 | 
|  |   1063 | 	TInt r=CheckMountAndEntryName(anOldName);
 | 
|  |   1064 | 	if (r!=KErrNone)
 | 
|  |   1065 | 		return(r);
 | 
|  |   1066 | 	if (IsIllegalFullName(aNewName))
 | 
|  |   1067 | 		return(KErrBadName);
 | 
|  |   1068 | 	return(KErrNone);
 | 
|  |   1069 | 	}
 | 
|  |   1070 | 
 | 
|  |   1071 | TInt TDrive::CheckDirectories(const TDesC& anOldName,const TDesC& aNewName)
 | 
|  |   1072 | //
 | 
|  |   1073 | // Return KErrAlreadyExists if aNewName exists and 
 | 
|  |   1074 | // KErrAccessDenied if anOldName is a directory being moved to a subdirectory of itself
 | 
|  |   1075 | //
 | 
|  |   1076 | 	{
 | 
|  |   1077 | 
 | 
|  |   1078 | 	TEntry entry;
 | 
|  |   1079 | 	TInt r=Entry(anOldName,entry);
 | 
|  |   1080 | 	if (r!=KErrNone)
 | 
|  |   1081 | 		return(r);
 | 
|  |   1082 | 	if (entry.IsDir())
 | 
|  |   1083 | 		{
 | 
|  |   1084 | 	   	//-- check the length of the destination directory name. It shall not exceed 253 characters.
 | 
|  |   1085 |         //-- aNewName looks like "\\dir1" i.e. drive letter and ':' is removed from the name and there is no trailing '\\' in this case. 
 | 
|  |   1086 | 
 | 
|  |   1087 |        	const TInt maxDirNameLength = KMaxFileName - 3;
 | 
|  |   1088 |         if(aNewName.Length() > maxDirNameLength)
 | 
|  |   1089 |             return KErrBadName;	
 | 
|  |   1090 | 		if(IsSubDir(aNewName,anOldName))
 | 
|  |   1091 | 			return(KErrInUse); // rename into a subdir of itself
 | 
|  |   1092 | 		if (LocateFileByPath(anOldName))
 | 
|  |   1093 | 			return(KErrInUse); // a file inside anOldName is open
 | 
|  |   1094 | 		}
 | 
|  |   1095 | 	else if (LocateFile(anOldName))
 | 
|  |   1096 | 		return(KErrInUse);
 | 
|  |   1097 | 	
 | 
|  |   1098 | 	r=Entry(aNewName,entry);
 | 
|  |   1099 | 	if (r!=KErrNone && r!=KErrNotFound)
 | 
|  |   1100 | 		return(r);
 | 
|  |   1101 | 	return(KErrNone);
 | 
|  |   1102 | 	}
 | 
|  |   1103 | 
 | 
|  |   1104 | TInt TDrive::Rename(const TDesC& anOldName,const TDesC& aNewName)
 | 
|  |   1105 | //
 | 
|  |   1106 | // Rename files or directories. No wild cards.
 | 
|  |   1107 | //
 | 
|  |   1108 | 	{
 | 
|  |   1109 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1110 | 	TInt r=CheckMountAndEntryNames(anOldName,aNewName);
 | 
|  |   1111 | 	if (r!=KErrNone)
 | 
|  |   1112 | 		return(r);
 | 
|  |   1113 | 	TPtrC oldEntryName(StripBackSlash(anOldName));
 | 
|  |   1114 | 	TPtrC newEntryName(StripBackSlash(aNewName));
 | 
|  |   1115 | 	r=CheckDirectories(oldEntryName,newEntryName);
 | 
|  |   1116 | 	if (r!=KErrNone)
 | 
|  |   1117 | 		return(r);
 | 
|  |   1118 | 	if(IsWriteProtected())
 | 
|  |   1119 | 		return(KErrAccessDenied);
 | 
|  |   1120 | 
 | 
|  |   1121 | 	// remove from closed queue
 | 
|  |   1122 | 	LocateClosedFile(anOldName, EFalse);
 | 
|  |   1123 | 	LocateClosedFile(aNewName, EFalse);
 | 
|  |   1124 | 
 | 
|  |   1125 | 	TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameL, EF32TraceUidFileSys, DriveNumber(), oldEntryName,newEntryName);
 | 
|  |   1126 | 	TRAP(r,CurrentMount().RenameL(oldEntryName,newEntryName))
 | 
|  |   1127 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameLRet, EF32TraceUidFileSys, r);
 | 
|  |   1128 | 
 | 
|  |   1129 | 	return(r);
 | 
|  |   1130 | 	}
 | 
|  |   1131 | 
 | 
|  |   1132 | TInt TDrive::Replace(const TDesC& anOldName,const TDesC& aNewName)
 | 
|  |   1133 | //
 | 
|  |   1134 | // Replace anOldName with aNewName atomically. No wild cards. No directories
 | 
|  |   1135 | //
 | 
|  |   1136 | 	{
 | 
|  |   1137 | 	TInt r=CheckMountAndEntryNames(anOldName,aNewName);
 | 
|  |   1138 | 	if (r!=KErrNone)
 | 
|  |   1139 | 		return(r);
 | 
|  |   1140 | 	TEntry entry;
 | 
|  |   1141 | 	r=Entry(aNewName,entry);
 | 
|  |   1142 | 	if (r!=KErrNotFound)
 | 
|  |   1143 | 		{
 | 
|  |   1144 | 		if (r!=KErrNone)
 | 
|  |   1145 | 			return(r);
 | 
|  |   1146 | 		if (entry.IsDir() || entry.IsReadOnly())
 | 
|  |   1147 | 			return(KErrAccessDenied);
 | 
|  |   1148 | 		if (LocateFile(aNewName))
 | 
|  |   1149 | 			return(KErrInUse);
 | 
|  |   1150 | 		}
 | 
|  |   1151 | 	r=Entry(anOldName,entry);
 | 
|  |   1152 | 	if (r!=KErrNone)
 | 
|  |   1153 | 		return(r);
 | 
|  |   1154 | 	if (entry.IsDir() || IsWriteProtected())
 | 
|  |   1155 | 		return(KErrAccessDenied);
 | 
|  |   1156 | 	if (LocateFile(anOldName))
 | 
|  |   1157 | 		return(KErrInUse);
 | 
|  |   1158 | 
 | 
|  |   1159 | 	// remove from closed queue
 | 
|  |   1160 | 	LocateClosedFile(anOldName, EFalse);
 | 
|  |   1161 | 	LocateClosedFile(aNewName, EFalse);
 | 
|  |   1162 | 
 | 
|  |   1163 | 	TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceL, EF32TraceUidFileSys, DriveNumber(), anOldName, aNewName);
 | 
|  |   1164 | 	TRAP(r,CurrentMount().ReplaceL(anOldName,aNewName))
 | 
|  |   1165 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceLRet, EF32TraceUidFileSys, r);
 | 
|  |   1166 | 
 | 
|  |   1167 | 	return(r);
 | 
|  |   1168 | 	}
 | 
|  |   1169 | 
 | 
|  |   1170 | TInt TDrive::Entry(const TDesC& aName,TEntry& anEntry)
 | 
|  |   1171 | //
 | 
|  |   1172 | // Get the entry details.
 | 
|  |   1173 | //
 | 
|  |   1174 | 	{
 | 
|  |   1175 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1176 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1177 | 	if (r!=KErrNone)
 | 
|  |   1178 | 		return(r);
 | 
|  |   1179 | 	TPtrC entryName(StripBackSlash(aName));
 | 
|  |   1180 | 	TRAP(r,DoEntryL(entryName,anEntry));
 | 
|  |   1181 | 	
 | 
|  |   1182 | 	if (r==KErrHidden)
 | 
|  |   1183 | 		r=KErrNotFound;	
 | 
|  |   1184 | 	else if (r==KErrPathHidden)
 | 
|  |   1185 | 		r=KErrPathNotFound;
 | 
|  |   1186 | 
 | 
|  |   1187 | 	return(r);
 | 
|  |   1188 | 	}
 | 
|  |   1189 | 
 | 
|  |   1190 | void TDrive::DoEntryL(const TDesC& aName, TEntry& anEntry)
 | 
|  |   1191 | //
 | 
|  |   1192 | // Get entry details
 | 
|  |   1193 | //
 | 
|  |   1194 | 	{
 | 
|  |   1195 | 	FlushCachedFileInfoL();
 | 
|  |   1196 | 
 | 
|  |   1197 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryL, EF32TraceUidFileSys, DriveNumber(), aName);
 | 
|  |   1198 | 	CurrentMount().EntryL(aName,anEntry);
 | 
|  |   1199 | 	TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryLRet, EF32TraceUidFileSys, 
 | 
|  |   1200 | 		KErrNone, anEntry.iAtt, 
 | 
|  |   1201 | 		I64LOW(anEntry.iModified.Int64()), I64HIGH(anEntry.iModified.Int64()), 
 | 
|  |   1202 | 		anEntry.iSize);
 | 
|  |   1203 | 
 | 
|  |   1204 | 	}
 | 
|  |   1205 | 
 | 
|  |   1206 | TInt TDrive::CheckAttributes(const TDesC& aName,TUint& aSetAttMask,TUint& aClearAttMask)
 | 
|  |   1207 | //
 | 
|  |   1208 | // Validate the changes against the current entry attributes
 | 
|  |   1209 | //
 | 
|  |   1210 | 	{
 | 
|  |   1211 | 
 | 
|  |   1212 | 	TEntry entry;
 | 
|  |   1213 | 	TRAPD(r,DoEntryL(aName,entry));
 | 
|  |   1214 | 	if (r!=KErrNone)
 | 
|  |   1215 | 		return(r);
 | 
|  |   1216 | 	ValidateAtts(entry.iAtt,aSetAttMask,aClearAttMask);
 | 
|  |   1217 | 	return(KErrNone);
 | 
|  |   1218 | 	}
 | 
|  |   1219 | 
 | 
|  |   1220 | TInt TDrive::SetEntry(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
 | 
|  |   1221 | //
 | 
|  |   1222 | // Set the entry details.
 | 
|  |   1223 | //
 | 
|  |   1224 | 	{
 | 
|  |   1225 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1226 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1227 | 	if (r!=KErrNone)
 | 
|  |   1228 | 		return(r);
 | 
|  |   1229 | 	TPtrC entryName(StripBackSlash(aName));
 | 
|  |   1230 | 	CFileCB* pF=LocateFile(entryName);
 | 
|  |   1231 | 	if (pF!=NULL)
 | 
|  |   1232 | 		return(KErrInUse);
 | 
|  |   1233 | 	r=CheckAttributes(entryName,aSetAttMask,aClearAttMask);
 | 
|  |   1234 | 	if (r!=KErrNone)
 | 
|  |   1235 | 		return(r);
 | 
|  |   1236 | 	if (IsWriteProtected())
 | 
|  |   1237 | 		return(KErrAccessDenied);
 | 
|  |   1238 | 	TTime nullTime(0);
 | 
|  |   1239 | 	if (aTime!=nullTime)
 | 
|  |   1240 | 		aSetAttMask|=KEntryAttModified;
 | 
|  |   1241 | 
 | 
|  |   1242 | 	TRACEMULT6(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryL, EF32TraceUidFileSys, 
 | 
|  |   1243 | 		DriveNumber(), aName, I64LOW(aTime.Int64()), I64HIGH(aTime.Int64()), aSetAttMask, aClearAttMask);
 | 
|  |   1244 | 	TRAP(r,CurrentMount().SetEntryL(entryName,aTime,aSetAttMask,aClearAttMask))
 | 
|  |   1245 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryLRet, EF32TraceUidFileSys, r);
 | 
|  |   1246 | 
 | 
|  |   1247 | 	return(r);
 | 
|  |   1248 | 	}
 | 
|  |   1249 | 
 | 
|  |   1250 | TInt TDrive::FileTemp(CFsRequest* aRequest,TInt& aHandle,const TDesC& aPath,TDes& aName,TUint aMode)
 | 
|  |   1251 | //
 | 
|  |   1252 | // Create a temporary file and return the file name.
 | 
|  |   1253 | //
 | 
|  |   1254 | 	{
 | 
|  |   1255 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1256 | 	aName=aPath;
 | 
|  |   1257 | 	TInt len=aName.Length();
 | 
|  |   1258 | 	TInt t=User::TickCount()&0xfffff;
 | 
|  |   1259 | 	aMode|=EFileWrite;
 | 
|  |   1260 | 	for (TInt retry=0;retry<KMaxTempNameAttempts;retry++)
 | 
|  |   1261 | 		{
 | 
|  |   1262 | 		aName.SetLength(len);
 | 
|  |   1263 | 		aName.AppendFormat(_L("TMP%05x.$$$"),t);
 | 
|  |   1264 | 		TEntry e;
 | 
|  |   1265 | 		TInt r=Entry(aName,e);
 | 
|  |   1266 | 		if (r!=KErrNone)
 | 
|  |   1267 | 			{
 | 
|  |   1268 | 			if (r!=KErrNotFound)
 | 
|  |   1269 | 				return(r);
 | 
|  |   1270 | 			return(FileOpen(aRequest,aHandle,aName,aMode,EFileCreate));
 | 
|  |   1271 | 			}
 | 
|  |   1272 | 		t=((t|1)*13)&0xfffff;
 | 
|  |   1273 | 		}
 | 
|  |   1274 | 	return(KErrGeneral);
 | 
|  |   1275 | 	}
 | 
|  |   1276 | 
 | 
|  |   1277 | LOCAL_C HBufC* CreateFileNameL(const TDesC& aName)
 | 
|  |   1278 | //
 | 
|  |   1279 | // Create a HBufC from aName
 | 
|  |   1280 | // Converts _L("\\F32.\\GROUP\\release.") to _L("\\F32\\GROUP\\release")
 | 
|  |   1281 | //
 | 
|  |   1282 | 	{
 | 
|  |   1283 | 	
 | 
|  |   1284 | 	TParsePtrC name(aName);
 | 
|  |   1285 | 	TFileName fileName;
 | 
|  |   1286 | 	fileName.Append(KPathDelimiter);
 | 
|  |   1287 | 	
 | 
|  |   1288 | 	if (name.Path().Length())
 | 
|  |   1289 | 		{
 | 
|  |   1290 | 		TInt pos=0;
 | 
|  |   1291 | 		TPtrC entry(NULL,0);
 | 
|  |   1292 | 		FOREVER
 | 
|  |   1293 | 			{
 | 
|  |   1294 | 			NextInPath(name.Path(),entry,pos);
 | 
|  |   1295 | 			if (entry.Length()==0)
 | 
|  |   1296 | 				break;
 | 
|  |   1297 | 			fileName.Append(entry);
 | 
|  |   1298 | 			fileName.Append(KPathDelimiter);
 | 
|  |   1299 | 			}
 | 
|  |   1300 | 		}
 | 
|  |   1301 | 
 | 
|  |   1302 | 	fileName.Append(name.Name());
 | 
|  |   1303 | 	if (name.Ext().Length()>1)
 | 
|  |   1304 | 		fileName.Append(name.Ext());
 | 
|  |   1305 | 	return(fileName.AllocL());
 | 
|  |   1306 | 	} 
 | 
|  |   1307 | 
 | 
|  |   1308 | void TDrive::FileOpenL(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB*& aFileCB,CFileShare*& aFileShare)
 | 
|  |   1309 | //
 | 
|  |   1310 | // Open/Create/Replace a file.
 | 
|  |   1311 | //
 | 
|  |   1312 | 	{
 | 
|  |   1313 | 	aFileCB=NULL;
 | 
|  |   1314 | 	aFileShare=NULL;
 | 
|  |   1315 | 	TInt r = CheckMount();
 | 
|  |   1316 | 	if (r!=KErrNone)
 | 
|  |   1317 | 		User::Leave(r);
 | 
|  |   1318 | 
 | 
|  |   1319 | 	if (IsIllegalFullName(aRequest->Src()))
 | 
|  |   1320 | 		User::Leave(KErrBadName);
 | 
|  |   1321 | 
 | 
|  |   1322 | 	if (CurrentMount().Locked())
 | 
|  |   1323 | 		User::Leave(KErrInUse);
 | 
|  |   1324 | 
 | 
|  |   1325 | 	if ((aMode & EFileWrite) != 0)
 | 
|  |   1326 | 		{
 | 
|  |   1327 | 		TDriveInfo driveInfo;
 | 
|  |   1328 | 		DriveInfo(driveInfo);
 | 
|  |   1329 | 		if (driveInfo.iType==EMediaRom || (driveInfo.iMediaAtt&KMediaAttWriteProtected)!=0)
 | 
|  |   1330 | 			User::Leave(KErrAccessDenied);
 | 
|  |   1331 | 		}
 | 
|  |   1332 | 
 | 
|  |   1333 | 	TShare share=(TShare)(aMode&KFileShareMask);
 | 
|  |   1334 | 	if (share==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
 | 
|  |   1335 | 		User::Leave(KErrArgument);
 | 
|  |   1336 | 	
 | 
|  |   1337 | 	if (aMode & EFileReadAsyncAll)
 | 
|  |   1338 | 		{
 | 
|  |   1339 | 		// Async read all mode is not compatible with EFileShareExclusive or EFileShareReadersOnly,
 | 
|  |   1340 | 		// as these modes prevent a writer from accessing the file and completing the request.
 | 
|  |   1341 | 		if(share == EFileShareExclusive || share == EFileShareReadersOnly)
 | 
|  |   1342 | 			User::Leave(KErrArgument);
 | 
|  |   1343 | 		}
 | 
|  |   1344 | 
 | 
|  |   1345 | 	// check for silly cache on / off combinations
 | 
|  |   1346 | 	const TUint KBadWriteMode = EFileWriteBuffered | EFileWriteDirectIO;
 | 
|  |   1347 | 	const TUint KBadReadMode = EFileReadBuffered | EFileReadDirectIO;
 | 
|  |   1348 | 	const TUint KBadReadAheadMode = EFileReadAheadOn | EFileReadAheadOff;
 | 
|  |   1349 | 	const TUint KBadReadAheadMode2 = EFileReadDirectIO | EFileReadAheadOn;
 | 
|  |   1350 | 	if (((aMode & KBadWriteMode) == KBadWriteMode) ||
 | 
|  |   1351 | 		((aMode & KBadReadMode) == KBadReadMode) ||
 | 
|  |   1352 | 		((aMode & KBadReadAheadMode) == KBadReadAheadMode) ||
 | 
|  |   1353 | 		((aMode & KBadReadAheadMode2) == KBadReadAheadMode2))
 | 
|  |   1354 | 		{
 | 
|  |   1355 | 		User::Leave(KErrArgument);
 | 
|  |   1356 | 		}
 | 
|  |   1357 | 
 | 
|  |   1358 | 	// Only allow delete on close for a newly created file.
 | 
|  |   1359 | 	if ((aMode & EDeleteOnClose) && (anOpen!=EFileCreate))
 | 
|  |   1360 | 		User::Leave(KErrArgument);
 | 
|  |   1361 | 
 | 
|  |   1362 | 	CFileCB* pF=LocateFile(aName);
 | 
|  |   1363 | 	CFileCache* pFileCache = NULL;
 | 
|  |   1364 | 	TBool openFile=EFalse;
 | 
|  |   1365 | 	if (pF!=NULL)
 | 
|  |   1366 | 		{
 | 
|  |   1367 | 		if (pF->iShare==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
 | 
|  |   1368 | 			User::Leave(KErrInUse);
 | 
|  |   1369 | 		if (anOpen==EFileCreate)
 | 
|  |   1370 | 			User::Leave(KErrAlreadyExists);
 | 
|  |   1371 | 		TInt r=ValidateShare(*pF,share);
 | 
|  |   1372 | 		if (r!=KErrNone)
 | 
|  |   1373 | 			User::Leave(r);
 | 
|  |   1374 | 		if ((r=pF->Open())!=KErrNone)
 | 
|  |   1375 | 			User::Leave(r);
 | 
|  |   1376 | 		aFileCB=pF;
 | 
|  |   1377 | 		pFileCache = pF->FileCache();
 | 
|  |   1378 | 		}
 | 
|  |   1379 | 	else
 | 
|  |   1380 | 		{
 | 
|  |   1381 | 		TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   1382 | 
 | 
|  |   1383 |         //-- construct CFileCB object, belonging to the corresponding mount
 | 
|  |   1384 |         pF = aFileCB = CurrentMount().NewFileL();
 | 
|  |   1385 | 
 | 
|  |   1386 | 		TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileLRet, EF32TraceUidFileSys, r, pF);
 | 
|  |   1387 | 		TDrive* createdDrive=!aRequest->SubstedDrive() ? this : aRequest->SubstedDrive();
 | 
|  |   1388 | 
 | 
|  |   1389 |     	HBufC* fileName = CreateFileNameL(aName);
 | 
|  |   1390 | 
 | 
|  |   1391 |         pF->InitL(this, createdDrive, fileName);
 | 
|  |   1392 | 
 | 
|  |   1393 | 
 | 
|  |   1394 | 		pF->iShare = share;
 | 
|  |   1395 | 		openFile=ETrue;
 | 
|  |   1396 | 		CurrentMount().iMountQ.AddLast(*pF);
 | 
|  |   1397 | 		Files->AddL(pF,ETrue);
 | 
|  |   1398 | 		}
 | 
|  |   1399 | 	
 | 
|  |   1400 |     CFileShare* pS=aFileShare=new(ELeave) CFileShare(pF);
 | 
|  |   1401 | 
 | 
|  |   1402 | 	// We need to call CFileCB::PromoteShare immediately after the CFileShare 
 | 
|  |   1403 | 	// instance is created since the destructor calls CFileCB::DemoteShare()
 | 
|  |   1404 | 	// which checks the share count is non-zero
 | 
|  |   1405 | 	pS->iMode=aMode;
 | 
|  |   1406 | 	pF->PromoteShare(pS);
 | 
|  |   1407 | 
 | 
|  |   1408 | 	pS->InitL();
 | 
|  |   1409 | 	aFileCB=NULL; 
 | 
|  |   1410 | 	FileShares->AddL(pS,ETrue);
 | 
|  |   1411 | 	aHandle=aRequest->Session()->Handles().AddL(pS,ETrue);
 | 
|  |   1412 | 
 | 
|  |   1413 | 
 | 
|  |   1414 | 	if (openFile)
 | 
|  |   1415 | 		{
 | 
|  |   1416 | 		TRACEMULT5(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenL, EF32TraceUidFileSys, DriveNumber(), aName, aMode, (TUint) anOpen, (TUint) pF);
 | 
|  |   1417 | 		CurrentMount().FileOpenL(aName,aMode,anOpen,pF);
 | 
|  |   1418 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenLRet, EF32TraceUidFileSys, KErrNone);
 | 
|  |   1419 | 
 | 
|  |   1420 | 		// Delete on close may now be safely flagged if required.
 | 
|  |   1421 | 		// The file did not exist on the media prior to the
 | 
|  |   1422 | 		// CMountCB::FileOpenL() call for the case of a create.
 | 
|  |   1423 | 		if ((aMode & EDeleteOnClose) && (anOpen==EFileCreate))
 | 
|  |   1424 | 			pF->SetDeleteOnClose();
 | 
|  |   1425 | 
 | 
|  |   1426 | 		TBool localBufferSuppport = (CurrentMount().LocalBufferSupport(pF) == KErrNone)?(TBool)ETrue:(TBool)EFalse;
 | 
|  |   1427 | 		pF->SetLocalBufferSupport(localBufferSuppport);
 | 
|  |   1428 | 		if (localBufferSuppport)
 | 
|  |   1429 | 			{
 | 
|  |   1430 | 			// if file exists on closed queue resurrect it or discard it,
 | 
|  |   1431 | 			// depending on the file open mode
 | 
|  |   1432 | 			pFileCache = LocateClosedFile(aName, anOpen == EFileOpen?(TBool)ETrue:(TBool)EFalse);
 | 
|  |   1433 | 			if (pFileCache)
 | 
|  |   1434 | 				{
 | 
|  |   1435 | 				pFileCache = pFileCache->ReNewL(*pS);	// NB may return NULL if caching not enabled
 | 
|  |   1436 | 				}
 | 
|  |   1437 | 			else
 | 
|  |   1438 | 				{
 | 
|  |   1439 | 				pFileCache = CFileCache::NewL(*pS);		// NB may return NULL if caching not enabled
 | 
|  |   1440 | 				}
 | 
|  |   1441 | 			if (pFileCache)
 | 
|  |   1442 | 				// set the cached size to be the same as the uncached size
 | 
|  |   1443 | 				pF->SetCachedSize64(pF->Size64());
 | 
|  |   1444 | 			}
 | 
|  |   1445 | 		else
 | 
|  |   1446 | 			{
 | 
|  |   1447 | 			__CACHE_PRINT(_L("TDrive::FileOpenL(), Local buffers not supported"));
 | 
|  |   1448 | 			}
 | 
|  |   1449 | 		}
 | 
|  |   1450 | 
 | 
|  |   1451 | 	// initialize share mode flags
 | 
|  |   1452 | 	if (pFileCache != NULL)
 | 
|  |   1453 | 		pFileCache->Init(*pS);
 | 
|  |   1454 | 	}
 | 
|  |   1455 | 
 | 
|  |   1456 | TInt TDrive::FileOpen(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen)
 | 
|  |   1457 | //
 | 
|  |   1458 | // Open/Create/Replace a file.
 | 
|  |   1459 | //
 | 
|  |   1460 | 	{
 | 
|  |   1461 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1462 | 	CFileCB* pF=NULL;
 | 
|  |   1463 | 	CFileShare* pS=NULL;
 | 
|  |   1464 | 	aHandle=0;
 | 
|  |   1465 | 	TRAPD(r,FileOpenL(aRequest,aHandle,aName,aMode,anOpen,pF,pS))
 | 
|  |   1466 | 
 | 
|  |   1467 | 	// Allow files > 2GB-1 to be opened only if EFileBigFile is specified in iMode
 | 
|  |   1468 | 	if (r == KErrNone && pS && ((TUint64)pS->File().Size64() > KMaxLegacyFileSize) && (!(pS->IsFileModeBig())))
 | 
|  |   1469 | 		r = KErrTooBig;
 | 
|  |   1470 | 
 | 
|  |   1471 | 	if (r!=KErrNone)
 | 
|  |   1472 | 		{
 | 
|  |   1473 | 		if (r==KErrHidden)
 | 
|  |   1474 | 			r=KErrNotFound;	
 | 
|  |   1475 | 		else if (r==KErrPathHidden)
 | 
|  |   1476 | 			r=KErrPathNotFound;
 | 
|  |   1477 | 
 | 
|  |   1478 | 		if(pF && !pS)
 | 
|  |   1479 | 			pF->Close();
 | 
|  |   1480 | 		CheckSubClose(pS,aHandle,aRequest->Session());
 | 
|  |   1481 | 		}
 | 
|  |   1482 | 	return(r);
 | 
|  |   1483 | 	}
 | 
|  |   1484 | 
 | 
|  |   1485 | void TDrive::DirOpenL(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType,CDirCB*& aDir)
 | 
|  |   1486 | //
 | 
|  |   1487 | // Open a directory listing. Leave on error.
 | 
|  |   1488 | //
 | 
|  |   1489 | 	{
 | 
|  |   1490 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   1491 | 
 | 
|  |   1492 |     CDirCB* pD = aDir = CurrentMount().NewDirL(); //-- construct CDirCB object, belonging to the corresponding mount
 | 
|  |   1493 | 
 | 
|  |   1494 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirLRet, EF32TraceUidFileSys, KErrNone, pD);
 | 
|  |   1495 | 	pD->InitL(this);
 | 
|  |   1496 | 	// modify resource counter after initialisation to ensure correct cleanup
 | 
|  |   1497 | 	AddResource(CurrentMount());
 | 
|  |   1498 | 	pD->iAtt=anAtt;
 | 
|  |   1499 | 	pD->iUidType=aUidType;
 | 
|  |   1500 | 	Dirs->AddL(pD,ETrue);
 | 
|  |   1501 | 	aHandle=aSession->Handles().AddL(pD,ETrue);
 | 
|  |   1502 | 
 | 
|  |   1503 | 	TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenL, EF32TraceUidFileSys, DriveNumber(), aName, (TUint) pD);
 | 
|  |   1504 | 	CurrentMount().DirOpenL(aName,pD);
 | 
|  |   1505 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenLRet, EF32TraceUidFileSys, KErrNone);
 | 
|  |   1506 | 	}
 | 
|  |   1507 | 
 | 
|  |   1508 | TInt TDrive::DirOpen(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType)
 | 
|  |   1509 | //
 | 
|  |   1510 | // Open a directory listing.
 | 
|  |   1511 | //
 | 
|  |   1512 | 	{
 | 
|  |   1513 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1514 | 	if (r!=KErrNone)
 | 
|  |   1515 | 		return(r);
 | 
|  |   1516 | 	if (CurrentMount().Locked())
 | 
|  |   1517 | 		return(KErrInUse);
 | 
|  |   1518 | 	CDirCB* pD=NULL;
 | 
|  |   1519 | 	aHandle=0;
 | 
|  |   1520 | 	TRAP(r,DirOpenL(aSession,aHandle,aName,anAtt,aUidType,pD));
 | 
|  |   1521 | 	
 | 
|  |   1522 | 	if (r==KErrHidden)
 | 
|  |   1523 | 		r=KErrNotFound;	
 | 
|  |   1524 | 	else if (r==KErrPathHidden)
 | 
|  |   1525 | 		r=KErrPathNotFound;
 | 
|  |   1526 | 
 | 
|  |   1527 | 	if (r!=KErrNone)
 | 
|  |   1528 | 		CheckSubClose(pD,aHandle,aSession);
 | 
|  |   1529 | 	return(r);
 | 
|  |   1530 | 	}
 | 
|  |   1531 | 
 | 
|  |   1532 | 
 | 
|  |   1533 | TInt TDrive::ReadFileSection(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
 | 
|  |   1534 | //
 | 
|  |   1535 | //	Starting from aPos, read aLength bytes of a file into a Trg, 
 | 
|  |   1536 | //	regardless of lock state
 | 
|  |   1537 | //
 | 
|  |   1538 | 	{
 | 
|  |   1539 | 	return ReadFileSection64(aName, aPos, aTrg, aLength, aMessage);
 | 
|  |   1540 | 	}
 | 
|  |   1541 | 
 | 
|  |   1542 | 
 | 
|  |   1543 | TInt TDrive::ReadFileSection64(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
 | 
|  |   1544 | //
 | 
|  |   1545 | //	Starting from aPos, read aLength bytes of a file into a Trg, 
 | 
|  |   1546 | //	regardless of lock state
 | 
|  |   1547 | //
 | 
|  |   1548 | 	{
 | 
|  |   1549 | 
 | 
|  |   1550 | 	// flush dirty data if already open
 | 
|  |   1551 | 	CFileCB* file;
 | 
|  |   1552 | 	IsFileOpen(aName, file);
 | 
|  |   1553 | 		if (file && file->FileCache())
 | 
|  |   1554 | 		{
 | 
|  |   1555 | 		if (file->FileCache()->FlushDirty() == CFsRequest::EReqActionBusy)
 | 
|  |   1556 | 			return CFsRequest::EReqActionBusy;
 | 
|  |   1557 | 		}
 | 
|  |   1558 | 
 | 
|  |   1559 | 	__PRINT(_L("TDrive::ReadSection"));
 | 
|  |   1560 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1561 | 	if (r!=KErrNone)
 | 
|  |   1562 | 		return(r);
 | 
|  |   1563 | 	TPtrC entryName(StripBackSlash(aName));
 | 
|  |   1564 | 
 | 
|  |   1565 | 	TRACETHREADID(aMessage);
 | 
|  |   1566 | 	TRACEMULT7(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionL, EF32TraceUidFileSys, 
 | 
|  |   1567 | 		DriveNumber(), aName, I64LOW(aPos), I64HIGH(aPos), (TUint) aTrg, aLength, I64LOW(threadId));
 | 
|  |   1568 | 	TRAP(r,ReadSectionL(entryName,aPos,aTrg,aLength,aMessage));
 | 
|  |   1569 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionLRet, EF32TraceUidFileSys, r);
 | 
|  |   1570 | 
 | 
|  |   1571 | 	if (r==KErrHidden)
 | 
|  |   1572 | 		r=KErrNotFound;	
 | 
|  |   1573 | 	else if (r==KErrPathHidden)
 | 
|  |   1574 | 		r=KErrPathNotFound;
 | 
|  |   1575 | 
 | 
|  |   1576 | 	return(r);
 | 
|  |   1577 | 	}
 | 
|  |   1578 | 
 | 
|  |   1579 | 
 | 
|  |   1580 | void TDrive::ReadSectionL(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
 | 
|  |   1581 | //
 | 
|  |   1582 | //	Starting from aPos, read aLength bytes of a file into a Trg, 
 | 
|  |   1583 | //	regardless of lock state
 | 
|  |   1584 | //
 | 
|  |   1585 | 	{
 | 
|  |   1586 | 	__PRINT(_L("TDrive::ReadSectionL"));
 | 
|  |   1587 | 	
 | 
|  |   1588 | 	FlushCachedFileInfoL();
 | 
|  |   1589 | 	CurrentMount().ReadSection64L(aName,aPos,aTrg,aLength,aMessage);
 | 
|  |   1590 | 	}
 | 
|  |   1591 | 
 | 
|  |   1592 | /**
 | 
|  |   1593 |     Check the disk's integrity
 | 
|  |   1594 | */
 | 
|  |   1595 | TInt TDrive::CheckDisk()
 | 
|  |   1596 | 	{
 | 
|  |   1597 | 	TInt r=CheckMount();
 | 
|  |   1598 | 	if (r==KErrNone)
 | 
|  |   1599 | 		TRAP(r,FlushCachedFileInfoL());
 | 
|  |   1600 | 	if (r==KErrNone)
 | 
|  |   1601 | 		{
 | 
|  |   1602 | 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1, EF32TraceUidFileSys, DriveNumber());
 | 
|  |   1603 | 		r=CurrentMount().CheckDisk();
 | 
|  |   1604 | 		TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1Ret, EF32TraceUidFileSys, r);
 | 
|  |   1605 | 		}
 | 
|  |   1606 | 	return(r);
 | 
|  |   1607 | 	}
 | 
|  |   1608 | 
 | 
|  |   1609 | /**
 | 
|  |   1610 |     @prototype
 | 
|  |   1611 | */
 | 
|  |   1612 | TInt TDrive::CheckDisk(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
 | 
|  |   1613 |     {
 | 
|  |   1614 | 	TInt r=CheckMount();
 | 
|  |   1615 | 	if (r==KErrNone)
 | 
|  |   1616 | 		TRAP(r,FlushCachedFileInfoL());
 | 
|  |   1617 | 	if (r==KErrNone)
 | 
|  |   1618 | 		{
 | 
|  |   1619 | 		TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
 | 
|  |   1620 | 		r=CurrentMount().CheckDisk(aOperation, aParam1, aParam2);
 | 
|  |   1621 | 		TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2Ret, EF32TraceUidFileSys, r);
 | 
|  |   1622 | 		}
 | 
|  |   1623 | 
 | 
|  |   1624 | 	return(r);
 | 
|  |   1625 |     }
 | 
|  |   1626 | 
 | 
|  |   1627 | TInt TDrive::ScanDrive()
 | 
|  |   1628 | 	{
 | 
|  |   1629 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1630 | 	TInt r=CheckMount();
 | 
|  |   1631 | 	if(r==KErrNone)
 | 
|  |   1632 | 		{
 | 
|  |   1633 | 		if(IsWriteProtected())
 | 
|  |   1634 | 			return(KErrAccessDenied);
 | 
|  |   1635 | 		TRAP(r,FlushCachedFileInfoL());
 | 
|  |   1636 | 		}
 | 
|  |   1637 | 	if(r!=KErrNone)
 | 
|  |   1638 | 		return r;
 | 
|  |   1639 | 
 | 
|  |   1640 | 	// Empty closed file queue
 | 
|  |   1641 | 	TClosedFileUtils::Remove(DriveNumber());
 | 
|  |   1642 | 
 | 
|  |   1643 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1, EF32TraceUidFileSys, DriveNumber());
 | 
|  |   1644 | 	r = CurrentMount().ScanDrive();
 | 
|  |   1645 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1Ret, EF32TraceUidFileSys, r);
 | 
|  |   1646 | 
 | 
|  |   1647 | 	return r;
 | 
|  |   1648 | 	}
 | 
|  |   1649 | 
 | 
|  |   1650 | 
 | 
|  |   1651 | /**
 | 
|  |   1652 |     @prototype
 | 
|  |   1653 | */
 | 
|  |   1654 | TInt TDrive::ScanDrive(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
 | 
|  |   1655 | 	{
 | 
|  |   1656 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1657 | 	TInt r=CheckMount();
 | 
|  |   1658 | 	if(r==KErrNone)
 | 
|  |   1659 | 		{
 | 
|  |   1660 | 		if(IsWriteProtected())
 | 
|  |   1661 | 			return(KErrAccessDenied);
 | 
|  |   1662 | 		TRAP(r,FlushCachedFileInfoL());
 | 
|  |   1663 | 		}
 | 
|  |   1664 | 	if(r!=KErrNone)
 | 
|  |   1665 | 		return r;
 | 
|  |   1666 | 
 | 
|  |   1667 | 	// Empty closed file queue
 | 
|  |   1668 | 	TClosedFileUtils::Remove(DriveNumber());
 | 
|  |   1669 | 
 | 
|  |   1670 | 	TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
 | 
|  |   1671 | 	r = CurrentMount().ScanDrive(aOperation, aParam1, aParam2);
 | 
|  |   1672 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2Ret, EF32TraceUidFileSys, r);
 | 
|  |   1673 | 
 | 
|  |   1674 | 	return r;
 | 
|  |   1675 | 	}
 | 
|  |   1676 | 
 | 
|  |   1677 | 
 | 
|  |   1678 | TInt TDrive::GetShortName(const TDesC& aName,TDes& aShortName)
 | 
|  |   1679 | //
 | 
|  |   1680 | // Get the short name associated with a long file name
 | 
|  |   1681 | //
 | 
|  |   1682 | 	{
 | 
|  |   1683 | 	TInt r=CheckMountAndEntryName(aName);
 | 
|  |   1684 | 	if (r!=KErrNone)
 | 
|  |   1685 | 		return(r);
 | 
|  |   1686 | 	TPtrC entryName(StripBackSlash(aName));
 | 
|  |   1687 | 
 | 
|  |   1688 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
 | 
|  |   1689 | 	TRAP(r,CurrentMount().GetShortNameL(entryName,aShortName));
 | 
|  |   1690 | 	TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameLRet, EF32TraceUidFileSys, r, aShortName);
 | 
|  |   1691 | 
 | 
|  |   1692 | 	return(r);
 | 
|  |   1693 | 	}
 | 
|  |   1694 | 
 | 
|  |   1695 | TInt TDrive::GetLongName(const TDesC& aShortName,TDes& aLongName)
 | 
|  |   1696 | //
 | 
|  |   1697 | // Get the long name associated with a short file name
 | 
|  |   1698 | //
 | 
|  |   1699 | 	{
 | 
|  |   1700 | 	TInt r=CheckMountAndEntryName(aShortName);
 | 
|  |   1701 | 	if (r!=KErrNone)
 | 
|  |   1702 | 		return(r);
 | 
|  |   1703 | 	TPtrC entryName(StripBackSlash(aShortName));
 | 
|  |   1704 | 
 | 
|  |   1705 | 	TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
 | 
|  |   1706 | 	TRAP(r,CurrentMount().GetLongNameL(entryName,aLongName));
 | 
|  |   1707 | 	TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameLRet, EF32TraceUidFileSys, r, aLongName);
 | 
|  |   1708 | 
 | 
|  |   1709 | 	return(r);
 | 
|  |   1710 | 	}
 | 
|  |   1711 | 
 | 
|  |   1712 | TInt TDrive::IsFileOpen(const TDesC& aFileName,CFileCB*& aFileCB)
 | 
|  |   1713 | //
 | 
|  |   1714 | // Query whether the file is open or not.
 | 
|  |   1715 | //
 | 
|  |   1716 | 	{
 | 
|  |   1717 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1718 | 
 | 
|  |   1719 | 	aFileCB = NULL;
 | 
|  |   1720 | 	
 | 
|  |   1721 | 	TEntry dumEntry;
 | 
|  |   1722 | 	TInt r=Entry(aFileName,dumEntry);
 | 
|  |   1723 | 	if (r!=KErrNone)
 | 
|  |   1724 | 		return(r);
 | 
|  |   1725 | 	if(dumEntry.iAtt&KEntryAttDir)
 | 
|  |   1726 | 		return KErrArgument;
 | 
|  |   1727 | 
 | 
|  |   1728 | 	Files->Lock();
 | 
|  |   1729 | 	TInt count=Files->Count();
 | 
|  |   1730 | 
 | 
|  |   1731 | 	// create a hash to speed up the search
 | 
|  |   1732 | 
 | 
|  |   1733 | 	TFileName foldedName;
 | 
|  |   1734 | 	TUint32 nameHash=0;
 | 
|  |   1735 | 	if (count > 0)
 | 
|  |   1736 | 		{
 | 
|  |   1737 | 		foldedName.CopyF(aFileName);
 | 
|  |   1738 | 		nameHash=CalcNameHash(foldedName);
 | 
|  |   1739 | 		}
 | 
|  |   1740 | 
 | 
|  |   1741 | 	while(count--)
 | 
|  |   1742 | 		{
 | 
|  |   1743 | 		CFileCB* file=(CFileCB*)(*Files)[count];
 | 
|  |   1744 | 
 | 
|  |   1745 | 		if ((&file->Drive()==this) && nameHash == file->NameHash() && file->FileNameF().Match(foldedName)!=KErrNotFound)
 | 
|  |   1746 | 			{
 | 
|  |   1747 | 			aFileCB = file;
 | 
|  |   1748 | 			break;
 | 
|  |   1749 | 			}
 | 
|  |   1750 | 		}
 | 
|  |   1751 | 	Files->Unlock();
 | 
|  |   1752 | 	return(KErrNone);
 | 
|  |   1753 | 	}
 | 
|  |   1754 | 
 | 
|  |   1755 | TInt TDrive::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
 | 
|  |   1756 | //
 | 
|  |   1757 | // Return the start of the file if it is in rom
 | 
|  |   1758 | //
 | 
|  |   1759 | 	{
 | 
|  |   1760 | 	TInt r=CheckMount();
 | 
|  |   1761 | 	if (r==KErrNone)
 | 
|  |   1762 | 		CurrentMount().IsFileInRom(aFileName,aFileStart);
 | 
|  |   1763 | 	return(r);
 | 
|  |   1764 | 	}
 | 
|  |   1765 | 
 | 
|  |   1766 | TBool TDrive::IsWriteProtected()
 | 
|  |   1767 | //
 | 
|  |   1768 | // return true if the media is write protected
 | 
|  |   1769 | //
 | 
|  |   1770 | 	{
 | 
|  |   1771 | //	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1772 | 	TDriveInfo drvInfo;
 | 
|  |   1773 | 	drvInfo.iMediaAtt=0;
 | 
|  |   1774 | 	if(Att() && iFSys)
 | 
|  |   1775 | 		FSys().DriveInfo(drvInfo,DriveNumber());
 | 
|  |   1776 | 	return((drvInfo.iMediaAtt&KMediaAttWriteProtected)!=0);
 | 
|  |   1777 | 	}
 | 
|  |   1778 | 
 | 
|  |   1779 | 
 | 
|  |   1780 | 
 | 
|  |   1781 | 
 | 
|  |   1782 | /**
 | 
|  |   1783 | Checks whether any resource that could write to disk is open on
 | 
|  |   1784 | the current mount.
 | 
|  |   1785 | 
 | 
|  |   1786 | @return True, if a resource that could write to disk is open on
 | 
|  |   1787 |         the current mount, false otherwise.
 | 
|  |   1788 | */
 | 
|  |   1789 | EXPORT_C TBool TDrive::IsWriteableResource() const
 | 
|  |   1790 | 	{
 | 
|  |   1791 | //	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1792 | 	if(iCurrentMount==NULL)
 | 
|  |   1793 | 		return(EFalse);
 | 
|  |   1794 | 	if(iCurrentMount->LockStatus()>0)
 | 
|  |   1795 | 		{
 | 
|  |   1796 | 		// check format subsessions
 | 
|  |   1797 | 		Formats->Lock();
 | 
|  |   1798 | 		TInt count=Formats->Count();
 | 
|  |   1799 | 		while(count--)
 | 
|  |   1800 | 			{
 | 
|  |   1801 | 			CFormatCB* format=(CFormatCB*)(*Formats)[count];
 | 
|  |   1802 | 			if(&format->Mount()==iCurrentMount)
 | 
|  |   1803 | 				{
 | 
|  |   1804 | 				Formats->Unlock();
 | 
|  |   1805 | 				return(ETrue);
 | 
|  |   1806 | 				}
 | 
|  |   1807 | 			}
 | 
|  |   1808 | 		Formats->Unlock();
 | 
|  |   1809 | 		// check raw disk subsessions
 | 
|  |   1810 | 		RawDisks->Lock();
 | 
|  |   1811 | 		count=RawDisks->Count();
 | 
|  |   1812 | 		while(count--)
 | 
|  |   1813 | 			{
 | 
|  |   1814 | 			CRawDiskCB* rawDisk=(CRawDiskCB*)(*RawDisks)[count];
 | 
|  |   1815 | 			if(&rawDisk->Mount()==iCurrentMount && !rawDisk->IsWriteProtected())
 | 
|  |   1816 | 				{
 | 
|  |   1817 | 				Formats->Unlock();
 | 
|  |   1818 | 				return(ETrue);
 | 
|  |   1819 | 				}
 | 
|  |   1820 | 			}
 | 
|  |   1821 | 		Formats->Unlock();
 | 
|  |   1822 | 		}
 | 
|  |   1823 | 	else if(iCurrentMount->LockStatus()<0)
 | 
|  |   1824 | 		{
 | 
|  |   1825 | 		// check file share subsessions
 | 
|  |   1826 | 		FileShares->Lock();
 | 
|  |   1827 | 		TInt count=FileShares->Count();
 | 
|  |   1828 | 		while(count--)
 | 
|  |   1829 | 			{
 | 
|  |   1830 | 			CFileShare* fileShare=(CFileShare*)(*FileShares)[count];
 | 
|  |   1831 | 			if (&fileShare->File().Mount()==iCurrentMount && ((fileShare->iMode&EFileWrite)!=0))
 | 
|  |   1832 | 				{
 | 
|  |   1833 | 				FileShares->Unlock();
 | 
|  |   1834 | 				return(ETrue);
 | 
|  |   1835 | 				}
 | 
|  |   1836 | 			}
 | 
|  |   1837 | 		FileShares->Unlock();
 | 
|  |   1838 | 		}
 | 
|  |   1839 | 	return(EFalse);
 | 
|  |   1840 | 	}
 | 
|  |   1841 | 
 | 
|  |   1842 | 
 | 
|  |   1843 | 
 | 
|  |   1844 | 
 | 
|  |   1845 | /**
 | 
|  |   1846 | Tests whether the current function can cause a write to disk.
 | 
|  |   1847 | 
 | 
|  |   1848 | @return True, if the current function can cause a write to disk,
 | 
|  |   1849 |         false otherwise.
 | 
|  |   1850 | */
 | 
|  |   1851 | EXPORT_C TBool TDrive::IsCurrentWriteFunction() const
 | 
|  |   1852 | 	{
 | 
|  |   1853 | //	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1854 | 	CDriveThread* pT=NULL;
 | 
|  |   1855 | 	TInt r=FsThreadManager::GetDriveThread(iDriveNumber, &pT);
 | 
|  |   1856 | 	__ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveCurrentWriteFunction));
 | 
|  |   1857 | 	return(pT->IsRequestWriteable());
 | 
|  |   1858 | 	}
 | 
|  |   1859 | 
 | 
|  |   1860 | 
 | 
|  |   1861 | 
 | 
|  |   1862 | 
 | 
|  |   1863 | TInt TDrive::ForceRemountDrive(const TDesC8* aMountInfo,TInt aMountInfoMessageHandle,TUint aFlags)
 | 
|  |   1864 | //
 | 
|  |   1865 | // Force a remount of the drive
 | 
|  |   1866 | //
 | 
|  |   1867 | 	{
 | 
|  |   1868 | 	__PRINT(_L("TDrive::ForceRemountDrive"));
 | 
|  |   1869 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1870 | 	if(iFSys==NULL)
 | 
|  |   1871 | 		return(KErrNotReady);
 | 
|  |   1872 | 	TInt r;
 | 
|  |   1873 | 	CMountCB* pM=NULL;
 | 
|  |   1874 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   1875 | 	TRAP(r,pM=FSys().NewMountL());
 | 
|  |   1876 | 	TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
 | 
|  |   1877 | 	if(r!=KErrNone)
 | 
|  |   1878 | 		return(r);
 | 
|  |   1879 | 	pM->SetDrive(this);
 | 
|  |   1880 | 
 | 
|  |   1881 | 	TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDrive, EF32TraceUidFileSys, 
 | 
|  |   1882 | 		DriveNumber(), aMountInfo, aMountInfoMessageHandle, aFlags);
 | 
|  |   1883 | 	r=pM->ForceRemountDrive(aMountInfo,aMountInfoMessageHandle,aFlags);
 | 
|  |   1884 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDriveRet, EF32TraceUidFileSys, r);
 | 
|  |   1885 | 
 | 
|  |   1886 | 	pM->Close();
 | 
|  |   1887 | 	return(r);
 | 
|  |   1888 | 	}
 | 
|  |   1889 | 
 | 
|  |   1890 | TBool TDrive::IsExtensionMounted(CProxyDriveFactory* aFactory)
 | 
|  |   1891 | //
 | 
|  |   1892 | // return ETrue if extension mounted on the drive
 | 
|  |   1893 | //
 | 
|  |   1894 | 	{
 | 
|  |   1895 | 	for(TInt i=0;i<iExtInfo.iCount;++i)
 | 
|  |   1896 | 		{
 | 
|  |   1897 | 		if(iExtInfo.iInfo[i].iFactory==aFactory)
 | 
|  |   1898 | 			return(ETrue);
 | 
|  |   1899 | 		}
 | 
|  |   1900 | 	return(EFalse);
 | 
|  |   1901 | 	}
 | 
|  |   1902 | 
 | 
|  |   1903 | TInt TDrive::MountExtension(CProxyDriveFactory* aFactory,TBool aIsPrimary)
 | 
|  |   1904 | //
 | 
|  |   1905 | // Mount an extension
 | 
|  |   1906 | //
 | 
|  |   1907 | 	{
 | 
|  |   1908 | 	__PRINT1(_L("TDrive::MountExtension aIsPrimary=%d"),aIsPrimary);
 | 
|  |   1909 | 	if(aIsPrimary)
 | 
|  |   1910 | 		{
 | 
|  |   1911 | 		__CHECK_MAINTHREAD();
 | 
|  |   1912 | 		// primary extension mounted before file system since it must be present
 | 
|  |   1913 | 		// for successful mount
 | 
|  |   1914 | 		__ASSERT_ALWAYS(!iFSys,Fault(EMountExtensionFSys));
 | 
|  |   1915 | 		if(iExtInfo.iCount!=0)
 | 
|  |   1916 | 			return(KErrAccessDenied);
 | 
|  |   1917 | 		iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
 | 
|  |   1918 | 		iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=ETrue;
 | 
|  |   1919 | 		return(KErrNone);
 | 
|  |   1920 | 		}
 | 
|  |   1921 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1922 | 	// must be a secondary extension
 | 
|  |   1923 | 	if(iFSys==NULL)
 | 
|  |   1924 | 		return(KErrNotReady);
 | 
|  |   1925 | 	TBool extSupported = iFSys->IsExtensionSupported();
 | 
|  |   1926 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECFileSystemIsExtensionSupported, EF32TraceUidFileSys, extSupported);
 | 
|  |   1927 | 	if(!extSupported)
 | 
|  |   1928 | 		return(KErrNotSupported);
 | 
|  |   1929 | 	if(IsExtensionMounted(aFactory))
 | 
|  |   1930 | 		return(KErrAlreadyExists);
 | 
|  |   1931 | 	if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
 | 
|  |   1932 | 		return(KErrInUse);
 | 
|  |   1933 | 	if(iExtInfo.iCount>=KMaxExtensionCount)
 | 
|  |   1934 | 		return(KErrAccessDenied);
 | 
|  |   1935 | 	iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
 | 
|  |   1936 | 	iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=EFalse;
 | 
|  |   1937 | 	// now dismount and mount so that the extension incorporated
 | 
|  |   1938 | 	Dismount();
 | 
|  |   1939 | 	TInt r=CheckMount();
 | 
|  |   1940 | 	// if mount fails then remove the secondary extension
 | 
|  |   1941 | 	if(r!=KErrNone)
 | 
|  |   1942 | 		{
 | 
|  |   1943 | 		--iExtInfo.iCount;
 | 
|  |   1944 | 		__ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount0));
 | 
|  |   1945 | 		}
 | 
|  |   1946 | 	return(r);
 | 
|  |   1947 | 	}
 | 
|  |   1948 | 
 | 
|  |   1949 | TInt TDrive::DismountExtension(CProxyDriveFactory* aFactory, TBool /*aIsPrimary*/)
 | 
|  |   1950 | //
 | 
|  |   1951 | // Dismount an extension
 | 
|  |   1952 | //
 | 
|  |   1953 | 	{
 | 
|  |   1954 | 	 __PRINT(_L("TDrive::DismountExtension"));
 | 
|  |   1955 | 	 __CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1956 | 
 | 
|  |   1957 | 	// Empty closed file queue
 | 
|  |   1958 | 	TClosedFileUtils::Remove(DriveNumber());
 | 
|  |   1959 | 
 | 
|  |   1960 | 	if(iExtInfo.iCount==0)
 | 
|  |   1961 | 		return(KErrNotFound);
 | 
|  |   1962 | 	if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
 | 
|  |   1963 | 		return(KErrInUse);
 | 
|  |   1964 | 	for(TInt i=0;i<iExtInfo.iCount;++i)
 | 
|  |   1965 | 		{
 | 
|  |   1966 | 		if(iExtInfo.iInfo[i].iFactory==aFactory)
 | 
|  |   1967 | 			{
 | 
|  |   1968 | 			// cannot dismount a primary extension without dismounting the file system
 | 
|  |   1969 | 			if(i==0 && iExtInfo.iInfo[i].iIsPrimary)
 | 
|  |   1970 | 				return(KErrAccessDenied);
 | 
|  |   1971 | 			// slide any remaining extensions down
 | 
|  |   1972 | 			for(TInt j=i+1;j<iExtInfo.iCount;++j)
 | 
|  |   1973 | 				iExtInfo.iInfo[j-1].iFactory=iExtInfo.iInfo[j].iFactory;
 | 
|  |   1974 | 			iExtInfo.iCount--;
 | 
|  |   1975 | 			__ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount1));
 | 
|  |   1976 | 			Dismount();
 | 
|  |   1977 | 			return(KErrNone);
 | 
|  |   1978 | 			}
 | 
|  |   1979 | 		}
 | 
|  |   1980 | 	return(KErrNotFound);
 | 
|  |   1981 | 	}
 | 
|  |   1982 | 
 | 
|  |   1983 | TInt TDrive::ExtensionName(TDes& aExtensionName,TInt aPos)
 | 
|  |   1984 | //
 | 
|  |   1985 | // Return the extension name
 | 
|  |   1986 | //
 | 
|  |   1987 | 	{
 | 
|  |   1988 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   1989 | 
 | 
|  |   1990 | 	if(iFSys==NULL)
 | 
|  |   1991 | 		return(KErrNotReady);
 | 
|  |   1992 | 
 | 
|  |   1993 | 	if(aPos<iExtInfo.iCount)
 | 
|  |   1994 | 		{
 | 
|  |   1995 | 		aExtensionName=iExtInfo.iInfo[aPos].iFactory->Name();
 | 
|  |   1996 | 		return(KErrNone);
 | 
|  |   1997 | 		}
 | 
|  |   1998 | 	return(KErrNotFound);
 | 
|  |   1999 | 	}
 | 
|  |   2000 | 
 | 
|  |   2001 | #if defined(_LOCKABLE_MEDIA)
 | 
|  |   2002 | 	
 | 
|  |   2003 | TInt TDrive::LockDevice(TMediaPassword& aOld,TMediaPassword& aNew,TBool aStore)
 | 
|  |   2004 | //
 | 
|  |   2005 | // Lock media device
 | 
|  |   2006 | //
 | 
|  |   2007 | 	{
 | 
|  |   2008 | 	__PRINT(_L("TDrive::LockDevice"));
 | 
|  |   2009 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2010 | 	if(iFSys==NULL)
 | 
|  |   2011 | 		return(KErrNotReady);
 | 
|  |   2012 | 	TInt r;
 | 
|  |   2013 | 	CMountCB* pM=NULL;
 | 
|  |   2014 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   2015 | 	TRAP(r,pM=FSys().NewMountL());
 | 
|  |   2016 | 	TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
 | 
|  |   2017 | 	if(r!=KErrNone)
 | 
|  |   2018 | 		return(r);
 | 
|  |   2019 | 	pM->SetDrive(this);
 | 
|  |   2020 | 
 | 
|  |   2021 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBLock, EF32TraceUidFileSys, DriveNumber(), aStore);
 | 
|  |   2022 | 	r=pM->Lock(aOld,aNew,aStore);
 | 
|  |   2023 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBLockRet, EF32TraceUidFileSys, r);
 | 
|  |   2024 | 
 | 
|  |   2025 | 	pM->Close();
 | 
|  |   2026 | 	return(r);
 | 
|  |   2027 | 	}
 | 
|  |   2028 | 
 | 
|  |   2029 | TInt TDrive::UnlockDevice(TMediaPassword& aPassword,TBool aStore)
 | 
|  |   2030 | //
 | 
|  |   2031 | // Unlock media device
 | 
|  |   2032 | //
 | 
|  |   2033 | 	{
 | 
|  |   2034 | 	__PRINT(_L("TDrive::UnlockDevice"));
 | 
|  |   2035 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2036 | 	if(iFSys==NULL)
 | 
|  |   2037 | 		return(KErrNotReady);
 | 
|  |   2038 | 	TInt r;
 | 
|  |   2039 | 	CMountCB* pM=NULL;
 | 
|  |   2040 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   2041 | 	TRAP(r,pM=FSys().NewMountL());
 | 
|  |   2042 | 	TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
 | 
|  |   2043 | 	if(r!=KErrNone)
 | 
|  |   2044 | 		return(r);
 | 
|  |   2045 | 
 | 
|  |   2046 | 	// reset mount failure count - which is likely to be non-zero if drive is locked
 | 
|  |   2047 | 	iMountFailures = 0;
 | 
|  |   2048 | 
 | 
|  |   2049 | 	pM->SetDrive(this);
 | 
|  |   2050 | 
 | 
|  |   2051 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlock, EF32TraceUidFileSys, DriveNumber(), aStore);
 | 
|  |   2052 | 	r=pM->Unlock(aPassword,aStore);
 | 
|  |   2053 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlockRet, EF32TraceUidFileSys, r);
 | 
|  |   2054 | 
 | 
|  |   2055 | 	pM->Close();
 | 
|  |   2056 | 	return(r);
 | 
|  |   2057 | 	}
 | 
|  |   2058 | 
 | 
|  |   2059 | TInt TDrive::ClearDevicePassword(TMediaPassword& aPassword)
 | 
|  |   2060 | //
 | 
|  |   2061 | // Clear password of media device
 | 
|  |   2062 | //
 | 
|  |   2063 | 	{
 | 
|  |   2064 | 	__PRINT(_L("TDrive::ClearDevicePassword"));
 | 
|  |   2065 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2066 | 	if(iFSys==NULL)
 | 
|  |   2067 | 		return(KErrNotReady);
 | 
|  |   2068 | 	TInt r;
 | 
|  |   2069 | 	CMountCB* pM=NULL;
 | 
|  |   2070 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   2071 | 	TRAP(r,pM=FSys().NewMountL());
 | 
|  |   2072 | 	TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
 | 
|  |   2073 | 	if(r!=KErrNone)
 | 
|  |   2074 | 		return(r);
 | 
|  |   2075 | 	pM->SetDrive(this);
 | 
|  |   2076 | 
 | 
|  |   2077 | 	// ClearPassword() will only work if the card is already unlocked. 
 | 
|  |   2078 | 	// If the stack powers down, the card will become locked, so now that TBusLocalDrive::Caps()
 | 
|  |   2079 | 	// no longer powers up ths stack, we need to unlock the card first - but ignore the error as 
 | 
|  |   2080 | 	// the stack may unlock from the password store.
 | 
|  |   2081 | 	TDriveInfo info;
 | 
|  |   2082 | 	DriveInfo(info);
 | 
|  |   2083 | 	if (info.iMediaAtt & KMediaAttLocked)
 | 
|  |   2084 | 		UnlockDevice(aPassword, EFalse);
 | 
|  |   2085 | 
 | 
|  |   2086 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPassword, EF32TraceUidFileSys, DriveNumber());
 | 
|  |   2087 | 	r=pM->ClearPassword(aPassword);
 | 
|  |   2088 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPasswordRet, EF32TraceUidFileSys, r);
 | 
|  |   2089 | 
 | 
|  |   2090 | 	pM->Close();
 | 
|  |   2091 | 	return(r);
 | 
|  |   2092 | 	}
 | 
|  |   2093 | 
 | 
|  |   2094 | TInt TDrive::EraseDevicePassword()
 | 
|  |   2095 | //
 | 
|  |   2096 | // Erase password from the media device
 | 
|  |   2097 | //
 | 
|  |   2098 | 	{
 | 
|  |   2099 | 	__PRINT(_L("TDrive::EraseDevicePassword"));
 | 
|  |   2100 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2101 | 	if(iFSys==NULL)
 | 
|  |   2102 | 		return(KErrNotReady);
 | 
|  |   2103 | 	TInt r;
 | 
|  |   2104 | 	CMountCB* pM=NULL;
 | 
|  |   2105 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
 | 
|  |   2106 | 	TRAP(r,pM=FSys().NewMountL());
 | 
|  |   2107 | 	TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
 | 
|  |   2108 | 	if(r!=KErrNone)
 | 
|  |   2109 | 		return(r);
 | 
|  |   2110 | 	pM->SetDrive(this);
 | 
|  |   2111 | 
 | 
|  |   2112 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePassword, EF32TraceUidFileSys, DriveNumber());
 | 
|  |   2113 | 	r=pM->ErasePassword();
 | 
|  |   2114 | 	TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePasswordRet, EF32TraceUidFileSys, r);
 | 
|  |   2115 | 
 | 
|  |   2116 | 	pM->Close();
 | 
|  |   2117 | 	return(r);
 | 
|  |   2118 | 	}
 | 
|  |   2119 | 
 | 
|  |   2120 | #else
 | 
|  |   2121 | 
 | 
|  |   2122 | TInt TDrive::LockDevice(TMediaPassword& /*aOld*/,TMediaPassword& /*aNew*/,TBool /*aStore*/)
 | 
|  |   2123 | //
 | 
|  |   2124 | // Lock media device
 | 
|  |   2125 | //
 | 
|  |   2126 | 	{
 | 
|  |   2127 | 	return(KErrNotSupported);
 | 
|  |   2128 | 	}
 | 
|  |   2129 | 
 | 
|  |   2130 | TInt TDrive::UnlockDevice(TMediaPassword& /*aPassword*/,TBool /*aStore*/)
 | 
|  |   2131 | //
 | 
|  |   2132 | // Unlock media device
 | 
|  |   2133 | //
 | 
|  |   2134 | 	{
 | 
|  |   2135 | 	return(KErrNotSupported);
 | 
|  |   2136 | 	}
 | 
|  |   2137 | 
 | 
|  |   2138 | TInt TDrive::ClearDevicePassword(TMediaPassword& /*aPassword*/)
 | 
|  |   2139 | //
 | 
|  |   2140 | // Clear password of media device
 | 
|  |   2141 | //
 | 
|  |   2142 | 	{
 | 
|  |   2143 | 	return(KErrNotSupported);
 | 
|  |   2144 | 	}
 | 
|  |   2145 | 
 | 
|  |   2146 | TInt TDrive::EraseDevicePassword(TMediaPassword& /*aPassword*/)
 | 
|  |   2147 | //
 | 
|  |   2148 | // Clear password of media device
 | 
|  |   2149 | //
 | 
|  |   2150 | 	{
 | 
|  |   2151 | 	return(KErrNotSupported);
 | 
|  |   2152 | 	}
 | 
|  |   2153 | 
 | 
|  |   2154 | #endif
 | 
|  |   2155 | 
 | 
|  |   2156 | 
 | 
|  |   2157 | 
 | 
|  |   2158 | 	
 | 
|  |   2159 | /**
 | 
|  |   2160 | Gets the current notification state, which indicates whether the client
 | 
|  |   2161 | is notified of any read or write failures.
 | 
|  |   2162 | 
 | 
|  |   2163 | The notification status is a property of the current session with
 | 
|  |   2164 | the file server, the value of which is stored in CSessionFs::iNotifyUser.
 | 
|  |   2165 | If set to ETrue, the client will receive notifications from the file system.
 | 
|  |   2166 | 
 | 
|  |   2167 | Called by CMountCB::GetNotifyUser().
 | 
|  |   2168 | 
 | 
|  |   2169 | @return True, if the client receives notifications from the file system,
 | 
|  |   2170 |         false otherwise.
 | 
|  |   2171 | 
 | 
|  |   2172 | @see CMountCB
 | 
|  |   2173 | */	
 | 
|  |   2174 | EXPORT_C TBool TDrive::GetNotifyUser()
 | 
|  |   2175 | 	{
 | 
|  |   2176 | 	__CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2177 | 	if(iDriveFlags & ENotifyOff)
 | 
|  |   2178 | 		return(EFalse);
 | 
|  |   2179 | 	else
 | 
|  |   2180 | 		{
 | 
|  |   2181 | 		CDriveThread* pT=NULL;
 | 
|  |   2182 | 		
 | 
|  |   2183 |         const TInt r=FsThreadManager::GetDriveThread(iDriveNumber,&pT);
 | 
|  |   2184 | 		
 | 
|  |   2185 |         //-- if this drive is synchronous, i.e. all requests are processed in the main FS thread,
 | 
|  |   2186 |         //-- pretend that user notifications are turned off to avoid panic in the assert below.
 | 
|  |   2187 |         //-- for synch. drives pT will always be NULL and it's not possible to obtain CSessionFs by drive number.
 | 
|  |   2188 |         if(r == KErrAccessDenied) 
 | 
|  |   2189 |             return EFalse;
 | 
|  |   2190 |         
 | 
|  |   2191 | 		__ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveGetNotifyUser));
 | 
|  |   2192 | 		return(pT->IsSessionNotifyUser());
 | 
|  |   2193 | 		}
 | 
|  |   2194 | 	}
 | 
|  |   2195 | 
 | 
|  |   2196 | 
 | 
|  |   2197 | 
 | 
|  |   2198 | 
 | 
|  |   2199 | /**
 | 
|  |   2200 | Dismounts the current mount. This is method is called from outside, so do some finalisation work on mount.
 | 
|  |   2201 | After calling this function there is no current mount on the drive.
 | 
|  |   2202 | */
 | 
|  |   2203 | EXPORT_C void TDrive::Dismount()
 | 
|  |   2204 | 	{
 | 
|  |   2205 | 	__PRINT1(_L("TDrive::Dismount() iCurrentMount:0x%x"),iCurrentMount);
 | 
|  |   2206 | 
 | 
|  |   2207 | 	iMountFailures = 0;
 | 
|  |   2208 | 	if (!iCurrentMount)
 | 
|  |   2209 | 		return;
 | 
|  |   2210 | 
 | 
|  |   2211 |     TRAP_IGNORE(FlushCachedFileInfoL());
 | 
|  |   2212 | 
 | 
|  |   2213 |     //-- try our best to finalise the mount (the mount can decide to do some job during finalisation, e.g. write some data)
 | 
|  |   2214 |     TRAP_IGNORE(iCurrentMount->FinaliseMountL());
 | 
|  |   2215 |     
 | 
|  |   2216 |     DoDismount();
 | 
|  |   2217 | 	}
 | 
|  |   2218 | 
 | 
|  |   2219 | 
 | 
|  |   2220 | 
 | 
|  |   2221 | 
 | 
|  |   2222 | /**
 | 
|  |   2223 | Forcibly dismounts the current mount and prevents it being remounted.
 | 
|  |   2224 | After calling this function there is no current mount on the drive.
 | 
|  |   2225 | */
 | 
|  |   2226 | void TDrive::ForceDismount()
 | 
|  |   2227 | 	{
 | 
|  |   2228 | 	__PRINT1(_L("TDrive::ForceDismount() iCurrentMount:0x%x"),iCurrentMount);
 | 
|  |   2229 | 
 | 
|  |   2230 | 	iMountFailures = 0;
 | 
|  |   2231 | 
 | 
|  |   2232 | 	if(!iCurrentMount)
 | 
|  |   2233 | 		return;
 | 
|  |   2234 |   
 | 
|  |   2235 | 	TRAP_IGNORE(FlushCachedFileInfoL());
 | 
|  |   2236 | 	iCurrentMount->SetDismounted(); //! this affects TDrive::ReMount()
 | 
|  |   2237 |     DoDismount();
 | 
|  |   2238 | 	}
 | 
|  |   2239 | 
 | 
|  |   2240 | /** 
 | 
|  |   2241 |     An internal method. Dismounts and closes a current mount. 
 | 
|  |   2242 |     This method must not involve writing data to the media, because it could have beeen physically changed before.
 | 
|  |   2243 |     Called only from TDrive::CheckMount().
 | 
|  |   2244 | */
 | 
|  |   2245 | void TDrive::DoDismount()
 | 
|  |   2246 |     {
 | 
|  |   2247 |     __PRINT1(_L("TDrive::DoDismount() iCurrentMount:0x%x"),iCurrentMount);
 | 
|  |   2248 | 
 | 
|  |   2249 |     iMountFailures = 0;
 | 
|  |   2250 | 
 | 
|  |   2251 | 	if (!iCurrentMount)
 | 
|  |   2252 | 		return;
 | 
|  |   2253 | 
 | 
|  |   2254 | 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismounted, EF32TraceUidFileSys, DriveNumber());
 | 
|  |   2255 |     iCurrentMount->Dismounted();
 | 
|  |   2256 | 	TRACE0(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismountedRet, EF32TraceUidFileSys);
 | 
|  |   2257 | 
 | 
|  |   2258 | 	iCurrentMount->Close();
 | 
|  |   2259 | 	iCurrentMount=NULL;
 | 
|  |   2260 |     }
 | 
|  |   2261 | 
 | 
|  |   2262 | 
 | 
|  |   2263 | /**
 | 
|  |   2264 | Return the number of active mounts associated with this drive.
 | 
|  |   2265 | (inactive mounts are those that have been forcibly dismounted)
 | 
|  |   2266 | */
 | 
|  |   2267 | TInt TDrive::ActiveMounts() const
 | 
|  |   2268 | 	{
 | 
|  |   2269 | 	TInt activeMounts = 0;
 | 
|  |   2270 | 
 | 
|  |   2271 | 	TInt idx = Mount().Count();
 | 
|  |   2272 | 	while(idx--)
 | 
|  |   2273 | 		{
 | 
|  |   2274 | 		if(((CMountCB*)Mount()[idx])->IsDismounted())
 | 
|  |   2275 | 			{
 | 
|  |   2276 | 			activeMounts++;
 | 
|  |   2277 | 			}
 | 
|  |   2278 | 		}
 | 
|  |   2279 | 
 | 
|  |   2280 | 	__PRINT1(_L("TDrive::ActiveMounts = %d"), activeMounts);
 | 
|  |   2281 | 	return activeMounts;
 | 
|  |   2282 | 	}
 | 
|  |   2283 | 
 | 
|  |   2284 | 
 | 
|  |   2285 | 
 | 
|  |   2286 | 
 | 
|  |   2287 | /**
 | 
|  |   2288 | Reactivate any disactive mounts on the drive following a dismount.
 | 
|  |   2289 | (inactive mounts are those that have been foribly dismounted)
 | 
|  |   2290 | */
 | 
|  |   2291 | void TDrive::ReactivateMounts()
 | 
|  |   2292 | 	{
 | 
|  |   2293 | 	__PRINT(_L("TDrive::ReactivateMounts"));
 | 
|  |   2294 | 	
 | 
|  |   2295 | 	TInt idx = Mount().Count();
 | 
|  |   2296 | 	while(idx--)
 | 
|  |   2297 | 		{
 | 
|  |   2298 | 		((CMountCB*)Mount()[idx])->SetDismounted(EFalse);
 | 
|  |   2299 | 		}
 | 
|  |   2300 | 	}
 | 
|  |   2301 | 
 | 
|  |   2302 | 
 | 
|  |   2303 | 
 | 
|  |   2304 | 
 | 
|  |   2305 | /**
 | 
|  |   2306 | Increments the drive dismount lock.  This defers dismount
 | 
|  |   2307 | of a file system until all clients have notified that it
 | 
|  |   2308 | is safe to do so.
 | 
|  |   2309 | 
 | 
|  |   2310 | @see RFs::NotifyDismount
 | 
|  |   2311 | */
 | 
|  |   2312 | void TDrive::DismountLock()
 | 
|  |   2313 | 	{ iDismountLock++; }
 | 
|  |   2314 | 
 | 
|  |   2315 | 
 | 
|  |   2316 | 
 | 
|  |   2317 | 
 | 
|  |   2318 | /**
 | 
|  |   2319 | Decrements the drive dismount lock.  When the lock count
 | 
|  |   2320 | reaches zero, the file system may be unmounted
 | 
|  |   2321 | 
 | 
|  |   2322 | @see RFs::AllowDismount
 | 
|  |   2323 | @return The new lock count
 | 
|  |   2324 | */
 | 
|  |   2325 | TInt TDrive::DismountUnlock()
 | 
|  |   2326 | 	{ 
 | 
|  |   2327 | 	return(--iDismountLock);
 | 
|  |   2328 | 	}
 | 
|  |   2329 | 
 | 
|  |   2330 | 
 | 
|  |   2331 | 
 | 
|  |   2332 | 
 | 
|  |   2333 | /**
 | 
|  |   2334 | Return the state of the dismount lock.
 | 
|  |   2335 | */
 | 
|  |   2336 | TBool TDrive::DismountLocked() const
 | 
|  |   2337 | 	{ return(iDismountLock); }
 | 
|  |   2338 | 
 | 
|  |   2339 | 
 | 
|  |   2340 | 
 | 
|  |   2341 | 
 | 
|  |   2342 | /**
 | 
|  |   2343 | Pending flag - set while waiting for clients to accept the dismount
 | 
|  |   2344 | */
 | 
|  |   2345 | void TDrive::SetDismountDeferred(TBool aPending)
 | 
|  |   2346 | 	{
 | 
|  |   2347 | 	if(aPending)
 | 
|  |   2348 | 		iDriveFlags |= EDismountDeferred;
 | 
|  |   2349 | 	else
 | 
|  |   2350 | 		iDriveFlags &= ~EDismountDeferred;
 | 
|  |   2351 | 	}
 | 
|  |   2352 | 
 | 
|  |   2353 | 
 | 
|  |   2354 | 
 | 
|  |   2355 | TInt TDrive::ControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2)
 | 
|  |   2356 | //
 | 
|  |   2357 | // General purpose test interface - .FSY specific.
 | 
|  |   2358 | //
 | 
|  |   2359 | 	{
 | 
|  |   2360 | 	TInt r=CheckMount();
 | 
|  |   2361 | 	if(r==KErrNone || (r==KErrInUse && iReason==KErrNone))
 | 
|  |   2362 | 		{
 | 
|  |   2363 | 		TRACETHREADID(aMessage);
 | 
|  |   2364 | 		TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIO, EF32TraceUidFileSys, 
 | 
|  |   2365 | 			DriveNumber(), aCommand, aParam1, aParam2, I64LOW(threadId));
 | 
|  |   2366 | 		r=CurrentMount().ControlIO(aMessage,aCommand,aParam1,aParam2);
 | 
|  |   2367 | 		TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIORet, EF32TraceUidFileSys, r);
 | 
|  |   2368 | 		}
 | 
|  |   2369 | 	return(r);
 | 
|  |   2370 | 	}
 | 
|  |   2371 | 
 | 
|  |   2372 | 
 | 
|  |   2373 | 
 | 
|  |   2374 | 
 | 
|  |   2375 | /**
 | 
|  |   2376 | Gets the drive attributes
 | 
|  |   2377 | 
 | 
|  |   2378 | @return The drive attributes.
 | 
|  |   2379 | */
 | 
|  |   2380 | EXPORT_C TUint TDrive::Att()
 | 
|  |   2381 | 	{
 | 
|  |   2382 | 	TUint a=iAtt;
 | 
|  |   2383 | 	return(a);
 | 
|  |   2384 | 	}
 | 
|  |   2385 | 
 | 
|  |   2386 | void TDrive::SetAtt(TUint aValue)
 | 
|  |   2387 | //
 | 
|  |   2388 | // set drive attributes
 | 
|  |   2389 | //
 | 
|  |   2390 | 	{
 | 
|  |   2391 | 	iAtt=aValue;
 | 
|  |   2392 | 	}
 | 
|  |   2393 | 
 | 
|  |   2394 | EXPORT_C TBool TDrive::IsDriveThread() const
 | 
|  |   2395 | //
 | 
|  |   2396 | // Return ETrue if the current thread id is the same as that of the drive's drive thread
 | 
|  |   2397 | //
 | 
|  |   2398 | 	{
 | 
|  |   2399 | 	return(FsThreadManager::IsDriveThread(iDriveNumber,ETrue));
 | 
|  |   2400 | 	}
 | 
|  |   2401 | 
 | 
|  |   2402 | EXPORT_C TBool TDrive::IsMainThread() const
 | 
|  |   2403 | //
 | 
|  |   2404 | // Reture ETrue if the current thread id is the same as that of the main file server thread
 | 
|  |   2405 | //
 | 
|  |   2406 | 	{
 | 
|  |   2407 | 	return(FsThreadManager::IsMainThread());
 | 
|  |   2408 | 	}
 | 
|  |   2409 | 
 | 
|  |   2410 | EXPORT_C void TDrive::DriveFault(TBool aDriveError) const
 | 
|  |   2411 | //
 | 
|  |   2412 | //
 | 
|  |   2413 | //
 | 
|  |   2414 | 	{
 | 
|  |   2415 | 	if(aDriveError)
 | 
|  |   2416 | 		::Fault(EFsDriveThreadError);
 | 
|  |   2417 | 	else
 | 
|  |   2418 | 		::Fault(EFsMainThreadError);
 | 
|  |   2419 | 	}
 | 
|  |   2420 | 
 | 
|  |   2421 | TInt TDrive::ClampFile(const TDesC& aName, TAny* aHandle)
 | 
|  |   2422 | //
 | 
|  |   2423 | // Attempt to clamp file
 | 
|  |   2424 | //
 | 
|  |   2425 | 	{
 | 
|  |   2426 | 	CMountCB* mount = (CMountCB*)&(CurrentMount());
 | 
|  |   2427 | 	TInt driveNo = DriveNumber();
 | 
|  |   2428 | 	return(mount->ClampFile(driveNo,aName,aHandle));
 | 
|  |   2429 | 	}
 | 
|  |   2430 | 
 | 
|  |   2431 | 
 | 
|  |   2432 | TInt TDrive::UnclampFile(CMountCB* aMount, RFileClamp* aHandle)
 | 
|  |   2433 | //
 | 
|  |   2434 | // Attempt to unclamp file
 | 
|  |   2435 | //
 | 
|  |   2436 | 	{
 | 
|  |   2437 | 	return(aMount->UnclampFile(aHandle));
 | 
|  |   2438 | 	}
 | 
|  |   2439 | 
 | 
|  |   2440 | 
 | 
|  |   2441 | TInt TDrive::ClampsOnDrive()
 | 
|  |   2442 | //
 | 
|  |   2443 | // Returns the number of clamps on this drive
 | 
|  |   2444 | //
 | 
|  |   2445 | 	{
 | 
|  |   2446 | 	Lock();
 | 
|  |   2447 | 	TInt clamps = IsMounted()?((CMountCB*)&(CurrentMount()))->NoOfClamps():0;	
 | 
|  |   2448 | 	UnLock();
 | 
|  |   2449 | 	return (clamps);
 | 
|  |   2450 | 	}
 | 
|  |   2451 | 
 | 
|  |   2452 | 
 | 
|  |   2453 | 
 | 
|  |   2454 | void TDrive::SetClampFlag(TBool aClamped)
 | 
|  |   2455 | //
 | 
|  |   2456 | //	Indicate if any files are clamped
 | 
|  |   2457 | //
 | 
|  |   2458 | 	{
 | 
|  |   2459 | 	if(aClamped)
 | 
|  |   2460 | 		iDriveFlags |= EClampPresent;
 | 
|  |   2461 | 	else
 | 
|  |   2462 | 		iDriveFlags &= ~EClampPresent;
 | 
|  |   2463 | 	}
 | 
|  |   2464 | 
 | 
|  |   2465 | 
 | 
|  |   2466 | TBool TDrive::ClampFlag()
 | 
|  |   2467 | //
 | 
|  |   2468 | // Report if any files are clamped
 | 
|  |   2469 | //
 | 
|  |   2470 | 	{ return(iDriveFlags & EClampPresent); }
 | 
|  |   2471 | 
 | 
|  |   2472 | 
 | 
|  |   2473 | 
 | 
|  |   2474 | #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
 | 
|  |   2475 | TInt TDrive::ClearDeferredDismount()
 | 
|  |   2476 | // debug-only function for testing
 | 
|  |   2477 | 	{
 | 
|  |   2478 | 	Lock();
 | 
|  |   2479 | 	FsNotify::HandleDismount(EFsDismountRegisterClient, DriveNumber(), ETrue, KErrNone);
 | 
|  |   2480 | 	SetDismountDeferred(EFalse);
 | 
|  |   2481 | 	UnLock();
 | 
|  |   2482 | 	return KErrNone;
 | 
|  |   2483 | 	}
 | 
|  |   2484 | #endif
 | 
|  |   2485 | 	
 | 
|  |   2486 | 
 | 
|  |   2487 | TInt TDrive::DismountProxyDrive()
 | 
|  |   2488 | //
 | 
|  |   2489 | // Dismount a proxy drive
 | 
|  |   2490 | //
 | 
|  |   2491 | 	{
 | 
|  |   2492 | 	 __PRINT(_L("TDrive::DismountProxyDrive"));
 | 
|  |   2493 | 	 __CHECK_DRIVETHREAD(iDriveNumber);
 | 
|  |   2494 | 
 | 
|  |   2495 | 	if (!IsProxyDrive(iDriveNumber) || LocalDrives::DriveNumberToLocalDriveNumber(iDriveNumber) == KDriveInvalid)
 | 
|  |   2496 | 		return KErrArgument;
 | 
|  |   2497 | 
 | 
|  |   2498 | 	if(iCurrentMount)
 | 
|  |   2499 | 		return(KErrInUse);
 | 
|  |   2500 | 
 | 
|  |   2501 | 
 | 
|  |   2502 | 	// Prevent ALL inactive mounts from EVER being remounted as they MAY (& probably do) point to
 | 
|  |   2503 | 	// this proxy-drive which we are about to delete....
 | 
|  |   2504 | 	// NB We could try to find out which mounts actually use this particular proxy-drive, but that's 
 | 
|  |   2505 | 	// a bit tricky to determine if there are extensions present as CMountCB::ProxyDrive() will only 
 | 
|  |   2506 | 	// return the first proxy drive in the chain.
 | 
|  |   2507 | 	TInt mCount=Mount().Count();
 | 
|  |   2508 | 	TInt u=(Mount().UniqueID()<<16);
 | 
|  |   2509 | 	for (TInt i=0;i<mCount;i++)
 | 
|  |   2510 | 		{
 | 
|  |   2511 | 		CMountCB* pM=(CMountCB*)Mount().At(u|i);
 | 
|  |   2512 | 		pM->SetProxyDriveDismounted();
 | 
|  |   2513 | 		}
 | 
|  |   2514 | 
 | 
|  |   2515 | 	FsThreadManager::LockDrive(iDriveNumber);
 | 
|  |   2516 | 	// Proxy drives are responsible for managing the drive threads...
 | 
|  |   2517 | 	FsThreadManager::CloseDrive(iDriveNumber);
 | 
|  |   2518 | 	LocalDrives::ClearProxyDriveMapping(iDriveNumber);
 | 
|  |   2519 | 	FsThreadManager::UnlockDrive(iDriveNumber);
 | 
|  |   2520 | 
 | 
|  |   2521 | 	return KErrNone;
 | 
|  |   2522 | 	}
 | 
|  |   2523 | 
 | 
|  |   2524 | //----------------------------------------------------------------------------
 | 
|  |   2525 | /**
 | 
|  |   2526 |     Complete, remove and delete notification requests
 | 
|  |   2527 |     @param  aCompletionCode completion code for some notifications
 | 
|  |   2528 | */
 | 
|  |   2529 | void TDrive::DoCompleteDismountNotify(TInt aCompletionCode)
 | 
|  |   2530 |     {
 | 
|  |   2531 |     FsNotify::HandleDismount(EFsDismountRegisterClient, iDriveNumber, ETrue, KErrNone);
 | 
|  |   2532 | 	FsNotify::HandleDismount(EFsDismountNotifyClients, iDriveNumber, ETrue, aCompletionCode);
 | 
|  |   2533 | 	FsNotify::HandleDismount(EFsDismountForceDismount, iDriveNumber, ETrue, aCompletionCode);
 | 
|  |   2534 |     }
 | 
|  |   2535 | 
 | 
|  |   2536 | //----------------------------------------------------------------------------
 | 
|  |   2537 | /**
 | 
|  |   2538 |     a helper method that allows forced dismounting current mount for volume formatting.
 | 
|  |   2539 | */
 | 
|  |   2540 | TInt TDrive::ForceUnmountFileSystemForFormatting()
 | 
|  |   2541 |     {
 | 
|  |   2542 |     TInt nRes;
 | 
|  |   2543 |     
 | 
|  |   2544 |     //-- check if there are any clamps on this drive
 | 
|  |   2545 |     nRes = ClampsOnDrive();
 | 
|  |   2546 |     if(nRes > 0)
 | 
|  |   2547 |         return KErrInUse;
 | 
|  |   2548 | 
 | 
|  |   2549 |     //-- purge all dirty data in the files associated with this drive's mount
 | 
|  |   2550 |     CDriveThread* pT=NULL;
 | 
|  |   2551 |     nRes = FsThreadManager::GetDriveThread(DriveNumber(), &pT);
 | 
|  |   2552 |     if(nRes == KErrNone && pT)
 | 
|  |   2553 |         {
 | 
|  |   2554 |         pT->CompleteReadWriteRequests();
 | 
|  |   2555 |         }
 | 
|  |   2556 | 
 | 
|  |   2557 |     PurgeDirty(CurrentMount());
 | 
|  |   2558 | 
 | 
|  |   2559 |     //-- 
 | 
|  |   2560 | 
 | 
|  |   2561 |     ForceDismount();
 | 
|  |   2562 | 
 | 
|  |   2563 |     DoCompleteDismountNotify(KErrDisMounted); //-- complete all dismount notifications
 | 
|  |   2564 | 
 | 
|  |   2565 |     return KErrNone;
 | 
|  |   2566 |     }
 | 
|  |   2567 | 
 | 
|  |   2568 | //----------------------------------------------------------------------------- 
 | 
|  |   2569 | /** 
 | 
|  |   2570 |     Instantiate CFormatCB object for formatting the file ssytem on the given TDrive.
 | 
|  |   2571 |     
 | 
|  |   2572 |     @param  aRequest            file server request object
 | 
|  |   2573 |     @param  aFmtHandle          out: format handle
 | 
|  |   2574 |     @param  aFmtMode            format mode
 | 
|  |   2575 |     @param  apLDFormatInfo      pointer to legacy parameters structure; NULL means "not used"
 | 
|  |   2576 |     @param  apVolFormatParam    pointer to the newparameters structure; NULL means "not used" 
 | 
|  |   2577 | 
 | 
|  |   2578 |     @return pointer to the instantiated CFormatCB object.
 | 
|  |   2579 | */
 | 
|  |   2580 | CFormatCB* TDrive::FormatOpenL(CFsRequest* aRequest, TInt& aFmtHandle, TFormatMode aFmtMode, const TLDFormatInfo* apLDFormatInfo, const TVolFormatParam* apVolFormatParam)
 | 
|  |   2581 |     {
 | 
|  |   2582 |     ASSERT(!(apLDFormatInfo && apVolFormatParam));  //-- these parameters are mutually exclusive
 | 
|  |   2583 |     
 | 
|  |   2584 |     TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatL, EF32TraceUidFileSys, &FSys(), DriveNumber()); 
 | 
|  |   2585 | 
 | 
|  |   2586 |     CFormatCB* pFormat = CurrentMount().NewFormatL(); 
 | 
|  |   2587 | 
 | 
|  |   2588 | 	TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatLRet, EF32TraceUidFileSys, KErrNone, pFormat); 
 | 
|  |   2589 | 	
 | 
|  |   2590 |     Formats->AddL(pFormat, ETrue); 
 | 
|  |   2591 | 	pFormat->InitL(this, aFmtMode); 
 | 
|  |   2592 | 
 | 
|  |   2593 |     if(aFmtMode & ESpecialFormat) 
 | 
|  |   2594 |         {
 | 
|  |   2595 |         if(apLDFormatInfo)
 | 
|  |   2596 |             {//-- the user has specified formatting parameters as TLDFormatInfo
 | 
|  |   2597 |             pFormat->SetFormatParameters(apLDFormatInfo);
 | 
|  |   2598 |             }
 | 
|  |   2599 |         else if(apVolFormatParam && apVolFormatParam->SomeParamsSet())
 | 
|  |   2600 |             {//-- the user has specified formatting parameters as TVolFormatParam
 | 
|  |   2601 |             TInt nRes = pFormat->SetFormatParameters(apVolFormatParam);
 | 
|  |   2602 |             User::LeaveIfError(nRes); //-- the particular file system might not support this feature
 | 
|  |   2603 |             }
 | 
|  |   2604 |         else
 | 
|  |   2605 |             {//-- this is a special case, ESpecialFormat is set, but no parameters provided at all;
 | 
|  |   2606 |              //-- invalidate CFormatCB::iSpecialInfo to make filesystem not to use it
 | 
|  |   2607 |             pFormat->SetFormatParameters((TLDFormatInfo*)NULL);
 | 
|  |   2608 |             }
 | 
|  |   2609 |         }
 | 
|  |   2610 |     
 | 
|  |   2611 | 
 | 
|  |   2612 | 	// modify resource counter after initialised to ensure correct cleanup 
 | 
|  |   2613 | 	AddDiskAccess(CurrentMount());	 
 | 
|  |   2614 | 	aFmtHandle = aRequest->Session()->Handles().AddL(pFormat, ETrue); 
 | 
|  |   2615 | 
 | 
|  |   2616 |     return pFormat;
 | 
|  |   2617 |     }
 | 
|  |   2618 | 
 | 
|  |   2619 | 
 | 
|  |   2620 | 
 | 
|  |   2621 | 
 | 
|  |   2622 | 
 | 
|  |   2623 | EXPORT_C void UNUSED1() {}
 | 
|  |   2624 | EXPORT_C void UNUSED2() {}
 | 
|  |   2625 | EXPORT_C void UNUSED3() {}
 | 
|  |   2626 | 
 | 
|  |   2627 | 
 | 
|  |   2628 | 
 | 
|  |   2629 | 
 | 
|  |   2630 | 
 | 
|  |   2631 | 
 | 
|  |   2632 | 
 | 
|  |   2633 | 
 | 
|  |   2634 | 
 |