userlibandfileserver/fileserver/sfile/sf_drv.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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