userlibandfileserver/fileserver/sfsrv/cl_fman.cpp
changeset 9 96e5fb8b040d
child 28 5b5d147c7838
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfsrv/cl_fman.cpp	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,2779 @@
+// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "cl_std.h"
+
+#define RETURNIFERROR(a,b,t)  					\
+	{											\
+	if ((a=b)!=KErrNone)						\
+		{										\
+		if(iStatus)								\
+			User::RequestComplete(iStatus,a);	\
+		TInt _t = t;							\
+		if (_t)	{TRACE1(UTF::EBorder, t, MODULEUID, a);}	\
+		return(a);								\
+		}										\
+	}
+
+#define RETURNIFERRORD(a,b,t)  		 			\
+	TInt a; 									\
+	RETURNIFERROR(a,b,t)
+
+const TUint KRecurseFlag	=	0x40000000;
+const TUint KScanDownFlag	=	0x20000000;
+const TUint KFManBusyFlag	=	0x10000000;
+const TUint KOverWriteFlag	=	0x08000000;
+const TUint KMoveRenameFlag	=	0x04000000;
+const TUint KCopyFromHandle	=	0x00000001;
+
+const TInt KPathIncGran=32;
+
+const TUint KMovingFilesMask = KEntryAttMatchExclude | KEntryAttDir;
+
+TInt ShrinkNames(RFs& aFs, TFileName& aParent, TFileName& aItem, TBool aAppend);
+
+LOCAL_C HBufC8* AllocateBuffer(TInt64 aLength)
+	{
+const TInt KBigBufSize = 512 * 1024;
+const TInt KMediumBufSize = 32 * 1024;
+const TInt KSmallBufSize = 4 * 1024;
+	// Min result shall be of TInt size
+	// Hence to suppress warning
+	TInt big = (TInt)(Min(aLength,(TInt64)KBigBufSize));
+	HBufC8* bufPtr=HBufC8::New(big);
+	if (bufPtr==NULL)
+		bufPtr=HBufC8::New(KMediumBufSize);
+	if (bufPtr==NULL)
+		bufPtr=HBufC8::New(KSmallBufSize);
+	return(bufPtr);
+	}
+
+LOCAL_C TInt IncPathLength(TInt aLen)
+	{
+	return(((aLen+KPathIncGran-1)/KPathIncGran)*KPathIncGran);
+	}
+
+LOCAL_C TInt CreateTargetNameFromSource(TDes& aTrgName, const TDesC& aTrgMask, const TDesC& aSrcName)
+// Replace the wildcards with letters from the matched file.
+	{
+	TFileName destName;
+	TParsePtrC trg(aTrgMask);
+	TParsePtrC src(aSrcName);
+	TPtrC mask(trg.NameAndExt());
+	TPtrC source(src.NameAndExt());
+	TInt steps = 1;
+	TBool starCharFound = EFalse;
+	if(mask.LocateReverse('.')!=KErrNotFound || aTrgMask.Right(1)==_L("*"))
+		{
+		mask.Set(trg.Name());
+		source.Set(src.Name());
+		steps = 2;
+		}
+	for(TInt i = 0; i < steps;
+	    i++, mask.Set(trg.ExtPresent() ? trg.Ext() : _L(".*")) , source.Set(src.Ext()))
+		{
+		TInt offset = 0;
+		starCharFound = EFalse;
+		while(offset < mask.Length())
+			{
+			TChar currentChar = mask[offset];
+			switch(currentChar)
+				{
+				case KMatchAny:
+					if(offset < source.Length() && !starCharFound)
+						{
+						destName.Append(source.Mid(offset));
+						starCharFound = ETrue;
+						}
+					break;
+				case KMatchOne:
+					if(offset < source.Length())
+				    {
+				    destName.Append(source[offset]);
+				    }
+					break;
+				default:
+					destName.Append(currentChar);
+					break;
+				}
+			offset++;
+			}
+		}
+	if(destName.Right(1) == _L("."))
+		{
+		destName.SetLength(destName.Length()-1);
+		}
+	if(aTrgName.Length()+destName.Length() > KMaxFileName)
+		{
+		return KErrBadName;
+		}
+	aTrgName.Append(destName);
+	return KErrNone;
+	}
+
+EXPORT_C MFileManObserver::TControl MFileManObserver::NotifyFileManStarted()
+/**
+Inform the observer that an operation is about to start.
+
+This is done immediately before each entry is processed.
+
+@return The implementation of this function should return:
+        MFileManObserver::EContinue, to allow processing of the current file
+        to proceed;
+        MFileManObserver::ECancel, to skip processing the current file and move
+        to the next file;
+        MFileManObserver::EAbort to abort the entire operation.
+        The default return value is MFileManObserver::EContinue.
+*/
+	{
+
+	return(EContinue);
+	}
+
+
+
+
+EXPORT_C MFileManObserver::TControl MFileManObserver::NotifyFileManOperation()
+/**
+Informs the observer that an operation, i.e. a copy or a move, is proceeding.
+
+Large files are copied and moved in stages.
+After each portion of the source file has been copied to the target, this
+function is called.
+
+It may be useful to call CFileMan::BytesTransferredByCopyStep() from this
+function to retrieve the current status of the operation.
+
+@return The implementation of this function should return:
+        MFileManObserver::ECancel, to cancel the current operation, closing the current source
+        and target files, the current target file is deleted.
+        If the operation is performed on several files, cancelling one will not abort whole batch.
+
+        MFileManObserver::EContinue, to continue with the operation.
+        The default return value is MFileManObserver::EContinue.
+
+@see CFileMan
+*/
+	{
+
+	return(EContinue);
+	}
+
+
+
+
+EXPORT_C MFileManObserver::TControl MFileManObserver::NotifyFileManEnded()
+/**
+Informs the observer that an operation is complete.
+
+This is done immediately after a directory entry has been processed.
+
+It may be useful to call CFileBase::GetLastError()
+and CFileBase::GetMoreInfoAboutError() from this function to retrieve
+information about how the operation ended.
+
+@return The implementation of this function should return:
+        MFileManObserver::EContinue or MFileManObserver::ECancel, to proceed
+        with processing the next entry. MFileManObserver::ECancel will not
+        cancel processing the current entry;
+        MFileManObserver::ERetry, to re-attempt processing the previous file;
+        MFileManObserver::EAbort, to abort the entire operation.
+        The default return value is MFileManObserver::EContinue.
+
+@see CFileBase
+*/
+	{
+
+	return(EContinue);
+	}
+
+
+
+
+EXPORT_C CFileBase::CFileBase(RFs& aFs)
+/**
+Protected default constructor.
+
+Note that the class is intended only as an abstract base for other classes.
+
+@param aFs File server session.
+*/
+	: iFs(aFs)
+	{
+	}
+
+
+
+
+EXPORT_C void CFileBase::ConstructL()
+/**
+Second phase constructor.
+*/
+	{
+
+	iScanner=CDirScan::NewL(iFs);
+	User::LeaveIfError(iSynchronizer.CreateLocal(0));
+	}
+
+
+
+
+EXPORT_C CFileBase::~CFileBase()
+/**
+Destructor.
+
+Frees resources prior to destruction of the object.
+*/
+	{
+
+	delete iScanner;
+	delete iDirList;
+	iSynchronizer.Close();
+	User::Free(iSessionPath);
+	}
+
+
+
+
+GLDEF_C void DoFManBaseOperationL(TAny* aPtr)
+//
+// File manager asynchronous thread
+//
+	{
+
+	CFileBase& fMan=*(CFileBase*)aPtr;
+	User::LeaveIfError(fMan.iFs.Connect());
+	User::LeaveIfError(fMan.iFs.SetSessionPath(*fMan.iSessionPath));
+	fMan.iNumberOfFilesProcessed = 0;
+	fMan.RunL();
+	}
+
+GLDEF_C TInt FManBaseThreadFunction(TAny* aPtr)
+//
+// Initialise New thread
+//
+	{
+
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	if (cleanup==NULL)
+		return(KErrNoMemory);
+	CFileBase& fMan=*(CFileBase*)aPtr;
+	fMan.iSynchronizer.Wait();
+	TRAPD(ret,DoFManBaseOperationL(aPtr));
+	if (ret==KErrNone)
+		ret=fMan.iLastError;
+	delete cleanup;
+	fMan.iSwitches=0;
+	fMan.iFs=fMan.iFsOld;
+	fMan.iStatus=NULL;
+	fMan.iFManThread.Close();
+	return(ret);
+	}
+
+
+
+
+EXPORT_C void CFileBase::RunInSeparateThreadL(TThreadFunction aThreadFunction)
+/**
+Creates a separate thread to run the command.
+
+@param aThreadFunction The thread function.
+*/
+	{
+	iSwitches|=KFManBusyFlag;
+	User::LeaveIfError(iFManThread.Create(KNullDesC,aThreadFunction,KDefaultStackSize,NULL,this));
+	iFManThread.SetPriority(EPriorityMuchLess);
+	TFileName sessionPath;
+	User::LeaveIfError(iFs.SessionPath(sessionPath));
+	if (iSessionPath==NULL)
+		iSessionPath=HBufC::NewL((sessionPath.Length()));
+	else if (iSessionPath->Des().MaxLength()<sessionPath.Length())
+		iSessionPath=iSessionPath->ReAllocL(IncPathLength(sessionPath.Length()));
+	iSessionPath->Des()=sessionPath;
+	iFsOld=iFs;
+	iLastError=KErrNone;
+	iFManThread.Logon(*iStatus);
+	iFManThread.Resume();
+	}
+
+
+
+
+EXPORT_C void CFileBase::RunL()
+/**
+Executes a command.
+
+@capability Dependent the capabilities required by this method, of the abstract class CFileBase,
+					  will be dependent on and provided by the concrete-class implementation of
+					  the DoOperationL method
+
+*/
+	{
+	if (iStatus && (iSwitches&KFManBusyFlag)==EFalse)
+		{
+		RunInSeparateThreadL(FManBaseThreadFunction);
+		return;
+		}
+
+	TBool copyFromHandle = (iSwitches & KCopyFromHandle)?(TBool)ETrue:(TBool)EFalse;
+
+	CDirScan::TScanDirection scanDir=(iSwitches&KScanDownFlag) ? CDirScan::EScanDownTree : CDirScan::EScanUpTree;
+
+	if (!copyFromHandle)
+		{
+		TRAP(iLastError,iScanner->SetScanDataL(iSrcFile.FullName(),iMatchEntry,ESortByName|EAscending,scanDir));
+		if (iLastError==KErrNone)
+			TRAP(iLastError,iScanner->NextL(iDirList));
+
+		if (iLastError!=KErrNone)
+			{
+			iErrorInfo=EInitializationFailed;
+			User::Leave(iLastError);
+			}
+		}
+
+	FOREVER
+		{
+		if (copyFromHandle || iDirList->Count())
+			{
+			iLastError=KErrNone;
+			iErrorInfo=ENoExtraInformation;
+			TInt action=(iObserver) ? iObserver->NotifyFileManStarted() : MFileManObserver::EContinue;
+			// Check if NotifyFileManStarted returned ECancel.
+			if ( action == MFileManObserver::ECancel)
+				iLastError=KErrCancel;
+			if (action==MFileManObserver::EContinue)
+				{
+				iNumberOfFilesProcessed++;
+				TRAP(iLastError,DoOperationL());
+				action=(iObserver) ? iObserver->NotifyFileManEnded() : MFileManObserver::EContinue;
+				}
+			else if(action==MFileManObserver::ERetry)
+			  {
+			  Panic(EFManBadValueFromObserver);
+			  }
+
+
+			switch(action)
+				{
+			case MFileManObserver::EContinue:
+			case MFileManObserver::ECancel:
+				break;
+			case MFileManObserver::ERetry:
+				continue;
+			case MFileManObserver::EAbort:
+				delete iDirList;
+				iDirList=NULL;
+				iCurrentEntry = 0;
+				User::Leave(KErrCancel);
+			default:
+				Panic(EFManBadValueFromObserver);
+				}
+			}
+		iCurrentEntry++;
+		if (copyFromHandle || iCurrentEntry>=iDirList->Count())
+			{
+			delete iDirList;
+			iDirList=NULL;
+			iCurrentEntry=0;
+
+			if (iSwitches&KRecurseFlag)
+				{
+				TRAPD(ret,iScanner->NextL(iDirList));
+				if (ret!=KErrNone && ret!=KErrPathNotFound)
+					{
+					iErrorInfo=EScanNextDirectoryFailed;
+					iLastError = ret;
+					User::Leave(iLastError);
+					}
+				}
+			if (iDirList==NULL)
+				{
+				CompleteOperationL();
+				return;
+				}
+			}
+		}
+	}
+
+
+
+
+EXPORT_C void CFileBase::SetObserver(MFileManObserver* anObserver)
+/**
+Sets the observer.
+
+Use this function to provide CFileMan with an MFileManObserver, or, if one
+already exists, to change the observer.
+
+@param anObserver File management observer.
+
+@see CFileMan
+@see MFileManObserver
+*/
+	{
+
+	iObserver=anObserver;
+	}
+
+
+
+
+EXPORT_C const TEntry& CFileBase::CurrentEntry()
+/**
+Gets the entry currently being processed.
+
+@return Contains the current entry.
+*/
+	{
+
+	__ASSERT_ALWAYS(iDirList && iCurrentEntry>=0 && iCurrentEntry<iDirList->Count(),Panic(EFManCurrentEntryInvalid));
+	return (*iDirList)[iCurrentEntry];
+	}
+
+
+
+
+EXPORT_C TPtrC CFileBase::AbbreviatedPath()
+/**
+Gets the abbreviated path of the file or directory currently being processed.
+
+The abbreviated path is its path relative to the top level directory
+specified in the operation.
+
+@return The abbreviated path.
+*/
+	{
+
+	return iScanner->AbbreviatedPath();
+	}
+
+
+
+
+EXPORT_C TPtrC CFileBase::FullPath()
+/**
+Gets the full path of the file or directory currently being processed.
+
+The full path includes the drive letter, path and filename.
+
+@return The full path.
+*/
+	{
+
+	return iScanner->FullPath();
+	}
+
+
+
+
+EXPORT_C TInt CFileBase::GetLastError()
+/**
+Gets the latest error code returned during a CFileMan
+operation.
+
+This function may be called from MFileManObserver::NotifyFileManEnded().
+
+@return KErrNone, or another error code that might have been
+        returned by a CFileMan operation.
+*/
+	{
+
+	return(iLastError);
+	}
+
+
+
+
+EXPORT_C TFileManError CFileBase::GetMoreInfoAboutError()
+/**
+Gets additional information about the latest error returned during
+a CFileMan operation.
+
+For example, if a rename fails, this function
+can be used to report whether the source or target name caused the problem.
+This information supplements that provided GetLastError().
+
+@return The extra information about the last CFileMan error.
+
+@see CFileMan
+@see CFileBase::GetLastError()
+*/
+	{
+
+	return(iErrorInfo);
+	}
+
+
+
+
+EXPORT_C CFileMan* CFileMan::NewL(RFs& aFs)
+/**
+Constructs and allocates memory for a new CFileMan object.
+
+@param aFs File server session.
+
+@return Newly created CFileMan object.
+*/
+	{
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManNewL1, MODULEUID, aFs.Handle());
+
+	CFileMan* fileMan=new(ELeave) CFileMan(aFs);
+	CleanupStack::PushL(fileMan);
+	fileMan->CFileBase::ConstructL();
+	CleanupStack::Pop();
+
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManNewL1Return, MODULEUID, fileMan);
+	return fileMan;
+	}
+
+
+
+
+EXPORT_C CFileMan* CFileMan::NewL(RFs& aFs,MFileManObserver* anObserver)
+/**
+Constructs and allocates memory for a new CFileMan object with an observer.
+
+@param aFs        File server session.
+@param anObserver File management observer.
+
+@return Newly created CFileMan object.
+*/
+	{
+	TRACE2(UTF::EBorder, UTraceModuleEfsrv::ECFileManNewL2, MODULEUID, aFs.Handle(), anObserver);
+
+	CFileMan* fileMan=new(ELeave) CFileMan(aFs);
+	CleanupStack::PushL(fileMan);
+	fileMan->CFileBase::ConstructL();
+	CleanupStack::Pop();
+	fileMan->SetObserver(anObserver);
+
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManNewL2Return, MODULEUID, fileMan);
+	return fileMan;
+	}
+
+
+
+
+CFileMan::CFileMan(RFs& aFs)
+//
+// Constructor and destructor
+//
+	: CFileBase(aFs)
+	{
+	}
+CFileMan::~CFileMan()
+	{
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManDestructor, MODULEUID, this);
+
+	TRACE0(UTF::EBorder, UTraceModuleEfsrv::ECFileManDestructorReturn, MODULEUID);
+	}
+
+
+EXPORT_C CFileMan::TAction CFileMan::CurrentAction()
+/**
+Gets the action which CFileMan is currently carrying out.
+
+@return The action which CFileMan is carrying out.
+*/
+	{
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCurrentAction, MODULEUID, this);
+
+	TAction action = ENone;
+
+	// Mapping table between internal and external action indicators.
+	switch(iAction)
+		{
+	case EInternalNone:
+		action = ENone;
+		break;
+	case EInternalAttribs:
+		action = EAttribs;
+		break;
+	case EInternalCopy:
+		action = ECopy;
+		break;
+	case EInternalCopyForMove:
+		action = EMove;
+		break;
+	case EInternalDelete:
+		action = EDelete;
+		break;
+	case EInternalRenameInvalidEntry:
+		action = ERenameInvalidEntry;
+		break;
+	case EInternalRenameForMove:
+	case EInternalRename:
+		action = ERename;
+		break;
+	case EInternalRmDir:
+		action = ERmDir;
+		break;
+	case EInternalCopyFromHandle:
+		action = ECopyFromHandle;
+		break;
+	default:
+		Panic(EFManUnknownAction);
+		}
+
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCurrentActionReturn, MODULEUID, action);
+	return (action);
+	}
+
+
+
+
+EXPORT_C void CFileMan::GetCurrentTarget(TFileName& aTrgName)
+/**
+Gets the name of the target file for the CFileMan operation currently
+being carried out.
+
+This function is relevant when copying, moving or renaming files.
+
+@param aTrgName The full path and filename of the target file for
+                the current CFileMan operation
+*/
+	{
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManGetCurrentTarget, MODULEUID, this);
+
+	GetSrcAndTrg(iTmpParse, aTrgName);
+
+	TRACEMULT1(UTF::EBorder, UTraceModuleEfsrv::ECFileManGetCurrentTargetReturn, MODULEUID, aTrgName);
+	}
+
+
+
+
+EXPORT_C void CFileMan::GetCurrentSource(TFileName& aSrcName)
+/**
+Gets the name of the source file or directory for the CFileMan operation
+currently being carried out.
+
+The source is the file or directory which is being copied, moved or deleted.
+
+@param aSrcName The full path and filename of the source file for the current
+                CFileMan operation.
+*/
+	{
+	TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManGetCurrentSource, MODULEUID, this);
+
+    TPtrC fullPath(FullPath());
+	iTmpParse.Set(CurrentEntry().iName, &fullPath, NULL);
+	aSrcName = iTmpParse.FullName();
+
+	TRACEMULT1(UTF::EBorder, UTraceModuleEfsrv::ECFileManGetCurrentSourceReturn, MODULEUID, aSrcName);
+	}
+
+void CFileMan::GetSrcAndTrg(TParse& aSrcName,TFileName& aTrgName)
+//
+// Get the current target for the operation
+//
+	{
+	TFileName fullpath = FullPath();
+	TInt ret = aSrcName.Set(CurrentEntry().iName, &fullpath, NULL);
+	if(ret == KErrBadName)
+		{
+		// Try heap variables first
+		TBool done = EFalse;
+		TFileName* current = new TFileName;
+		if (current != NULL)
+			{
+			current->Copy(CurrentEntry().iName);
+
+			ret = ShrinkNames(iFs, fullpath, *current, EFalse);
+			if(ret == KErrNone)
+				{
+				ret = aSrcName.Set(*current, &fullpath, NULL);
+				done = ETrue;
+				}
+			delete current;
+			}
+
+		if (!done) //heap method failed
+			{
+			TFileName current = CurrentEntry().iName;
+			ret = ShrinkNames(iFs, fullpath, current, EFalse);
+			if(ret == KErrNone)
+				{
+				ret = aSrcName.Set(current, &fullpath, NULL);
+				}
+			}
+		}
+	__ASSERT_DEBUG(ret == KErrNone, Panic(EBadLength));
+	aTrgName=iTrgFile.DriveAndPath();
+	TPtrC relPath=iScanner->AbbreviatedPath();
+	aTrgName.Append(relPath.Right(relPath.Length()-1));
+	CreateTargetNameFromSource(aTrgName,iTrgFile.NameAndExt(),aSrcName.NameAndExt());
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::BytesTransferredByCopyStep()
+/**
+Gets the number of bytes transferred during a copy or move operation.
+
+Large files are copied and moved in stages. After each portion of
+the source file has been copied to the target, the number of bytes
+transferred is updated. This function may be called
+from MFileManObserver::NotifyFileManOperation()
+and may be used to support the increment of progress bars.
+
+@return The number of bytes transferred.
+*/
+	{
+	TRACE2(UTF::EBorder, UTraceModuleEfsrv::ECFileManBytesTransferredByCopyStep, MODULEUID, this, iBytesTransferred);
+
+	return(iBytesTransferred);
+	}
+
+
+
+
+LOCAL_C void MakeParseWild(TParse& aParse, TFileName& aName)
+//
+// Append _L("\\*") or _L("*") to aParse
+//
+	{
+	if(!aParse.IsWild())
+		{
+		aName = aParse.FullName();
+		if (aParse.NamePresent() || aParse.ExtPresent())
+			{
+			if (aName.Length()<=254)
+				aName.Append(_L("\\*"));
+			}
+		else
+			{
+			if (aName.Length()<=255)
+				aName.Append(_L("*"));
+			}
+		aParse.Set(aName,NULL,NULL);
+		}
+	}
+
+
+void CFileMan::CheckForDirectory()
+//
+// If iTrgFile is a directory set target to iTrgFile\\*
+//
+	{
+	TInt trg = iFs.Entry(iTrgFile.FullName(), iTmpEntry);
+	if (trg==KErrNone && iTmpEntry.iAtt&KEntryAttDir)
+		MakeParseWild(iTrgFile, iTmpName1);
+	TInt src = iFs.Entry(iSrcFile.FullName(), iTmpEntry);
+	if (src==KErrNone && iTmpEntry.iAtt&KEntryAttDir)
+		{
+		MakeParseWild(iSrcFile, iTmpName1);
+		if (trg==KErrNotFound && (iSwitches&KRecurseFlag))
+			MakeParseWild(iTrgFile, iTmpName1);
+		}
+	}
+
+void CFileMan::DoSynchronize(TInt aRetValue)
+//
+// Synchronise with fmanthread
+//
+	{
+
+	if (iStatus && aRetValue==KErrNone)
+		iSynchronizer.Signal(); // FManThread started
+	if (iStatus && aRetValue!=KErrNone)
+		iStatus=NULL; // FManThread failed to start
+	}
+
+LOCAL_C void NextInPath(const TDesC& aPath,TPtrC& anEntry,TInt& aPos)
+//
+// Returns the next entry in the path
+//
+	{
+
+	anEntry.Set(NULL,0);
+	if ((aPos+1)>=aPath.Length())
+		return;
+	TPtrC path(aPath.Mid(aPos+1)); // Skip delimiter
+	TInt delimiterPos=path.Locate(KPathDelimiter);
+	if (delimiterPos==KErrNotFound)
+		delimiterPos=aPath.Length()-(aPos+1);
+	if (delimiterPos<=0)
+		return;
+
+	if (path[delimiterPos-1]==KExtDelimiter) // return "F32." as "F32"
+		anEntry.Set(aPath.Mid(aPos+1,delimiterPos-1));
+	else
+		anEntry.Set(aPath.Mid(aPos+1,delimiterPos));
+	aPos+=delimiterPos+1;
+	}
+
+LOCAL_C TBool ComparePaths(const TDesC& aPath1,const TDesC& aPath2)
+//
+// Return ETrue if the paths are identical
+// To catch case "\\F32.\\GROUP\\" == "\\F32\\GROUP\\"
+//
+	{
+
+	TPtrC entry1(NULL,0);
+	TPtrC entry2(NULL,0);
+	TInt pos1=0;
+	TInt pos2=0;
+
+	do {
+		NextInPath(aPath1,entry1,pos1);
+		NextInPath(aPath2,entry2,pos2);
+		if (entry1.MatchF(entry2)==KErrNotFound)
+			return(EFalse);
+		} while (entry1.Length() && entry2.Length());
+
+	return(ETrue);
+	}
+
+EXPORT_C TBool FileNamesIdentical(const TDesC& aFileName1,const TDesC& aFileName2)
+//
+// Return ETrue if the filenames (and paths) are identical
+// NB "Agenda" == "AGENda."
+//
+	{
+
+	TParsePtrC file1(aFileName1);
+	TParsePtrC file2(aFileName2);
+	if (file1.Drive().MatchF(file2.Drive())==KErrNotFound)
+		return(EFalse);
+	if (file1.Name().MatchF(file2.Name())==KErrNotFound)
+		return(EFalse);
+	if (ComparePaths(file1.Path(),file2.Path())==EFalse)
+		return(EFalse);
+	if (file1.Ext().Length()==0 || file2.Ext().Length()==0)
+		{ // Agenda == Agenda.
+		if (file1.Ext().Length()==1 || file2.Ext().Length()==1)
+			return(ETrue);
+		}
+	if (file1.Ext().MatchF(file2.Ext())==KErrNotFound &&
+		file1.NameAndExt().MatchF(file2.NameAndExt())==KErrNotFound)
+		return(EFalse);
+	return(ETrue);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Attribs(const TDesC& aName,TUint aSetMask,TUint aClearMask,const TTime& aTime,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Sets or clears attributes for one or more files using two bitmasks.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param aName      Path indicating the file(s) whose attributes are to be
+                  changed. Any path components which are not specified
+                  here will be taken from the session path.
+                  Use wildcards to specify more than one file.
+@param aSetMask   Bitmask indicating the attributes to be set.
+@param aClearMask Bitmask indicating the attributes to be cleared.
+                  For more information, see KEntryAttNormal and the other
+                  file/directory attributes.
+@param aTime      Contains the new modification date and time for the files, in UTC.
+                  To preserve the file's timestamps, specify a TTime value of 0.
+@param aSwitches  Specify zero for no recursion;
+                  CFileMan::ERecurse for recursion.
+                  By default, the synchronous variant of this function operates
+                  non-recursively.
+@param aStatus    The request status object. On request completion,
+                  indicates how the request completed:
+                  KErrNone, if successful, otherwise one of the other system-wide error
+                  codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability Dependent If aName is /Sys then Tcb capability is required.
+@capability Dependent If aName begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If aName is /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT8(UTF::EBorder, UTraceModuleEfsrv::ECFileManAttribs1, MODULEUID,
+		(TUint) this, aName, aSetMask, aClearMask, I64LOW(aTime.Int64()), I64HIGH(aTime.Int64()), aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = Attribs(aName,aSetMask,aClearMask,aTime,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManAttribs1Return, MODULEUID, r);
+	return r;
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Attribs(const TDesC& aName,TUint aSetMask,TUint aClearMask,const TTime& aTime,TUint aSwitches)
+/**
+Sets or clears attributes for one or more files using two bitmasks
+
+This is a synchronous function.
+
+The first bitmask specifies the attributes to be set.
+The second specifies the attributes to be cleared.
+The date and time of the files' last modification can also be changed.
+
+The function can operate recursively or non-recursively.
+When operating non-recursively, only the matching files located in the directory
+specified in aName are affected. When operating recursively, all matching files
+in the directory hierarchy below the directory specified in aName will be affected.
+
+Notes:
+
+1. A panic is raised if any attribute is specified in both bitmasks.
+
+2. Attempting to change the attributes for an open file results in an error
+   for that file, as retrieved by CFileBase::GetLastError().
+
+3. An attempt to set or clear the KEntryAttDir or KEntryAttVolume attribute
+   for a file or directory will have no effect.
+
+@param aName      Path indicating the file(s) whose attributes are to be
+                  changed. Any path components which are not specified
+                  here will be taken from the session path.
+                  Use wildcards to specify more than one file.
+@param aSetMask   Bitmask indicating the attributes to be set.
+@param aClearMask Bitmask indicating the attributes to be cleared.
+                  For more information, see KEntryAttNormal and the other
+                  file/directory attributes.
+@param aTime      Contains the new modification date and time for the files, in UTC.
+                  To preserve the file's timestamps, specify a TTime value of 0.
+@param aSwitches  Specify zero for no recursion;
+                  CFileMan::ERecurse for recursion.
+                  By default, the synchronous variant of this function operates
+                  non-recursively.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+
+@capability Dependent If aName is /Sys then Tcb capability is required.
+@capability Dependent If aName begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If aName is /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT7(UTF::EBorder, UTraceModuleEfsrv::ECFileManAttribs2, MODULEUID,
+		(TUint) this, aName, aSetMask, aClearMask, I64LOW(aTime.Int64()), I64HIGH(aTime.Int64()), aSwitches);
+
+	TInt ret;
+	if (iSwitches&KFManBusyFlag)
+		{
+		ret = KErrInUse;
+		}
+	else
+		{
+		SetFlags(aSwitches&EOverWrite,aSwitches&ERecurse,ETrue,EFalse);
+		RETURNIFERRORD(r,iFs.Parse(aName,iSrcFile),UTraceModuleEfsrv::ECFileManAttribs2Return);
+		iSetMask=aSetMask;
+		iClearMask=aClearMask;
+		iTime=aTime;
+		iAction = EInternalAttribs;
+		iMatchEntry=KEntryAttMaskSupported; // all entries
+		iNumberOfFilesProcessed = 0;
+		TRAP(r,RunL());
+		ret=(r==KErrNone) ? iLastError : r;
+		DoSynchronize(r);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManAttribs2Return, MODULEUID, ret);
+	return(ret);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Copy(const TDesC& anOld,const TDesC& aNew,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Copies one or more files.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param anOld     Path indicating the file(s) to be copied.
+                 Any path components which are not specified here will be
+                 taken from the session path.
+@param aNew      Path indicating the directory into which the file(s) are to be copied.
+				 Any path components which are not specified here will be
+                 taken from the session path
+@param aSwitches Specify zero for no overwriting and no recursion;
+                 CFileMan::EOverWrite to overwrite files with the same name;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function operates
+                 non-recursively and with overwriting.
+@param aStatus   The request status object. On request completion,
+                 indicates how the request completed:
+                 KErrNone, if successful, otherwise one of the other system-wide error
+                 codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability AllFiles
+
+@capability Dependent If the path for aNew begins with /Sys then Tcb capability is required.
+@capability Dependent If the path for aNew begins with /Resource then Tcb capability is required
+
+*/
+	{
+	TRACEMULT5(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy1, MODULEUID,
+		(TUint) this, anOld, aNew, aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		r = KErrInUse;
+	else
+		{
+		iStatus=&aStatus;
+		r = Copy(anOld,aNew,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy1Return, MODULEUID, r);
+	return(r);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Copy(const TDesC& anOld,const TDesC& aNew,TUint aSwitches)
+/**
+Copies one or more files.
+
+This is a synchronous function.
+
+NB the following applies to files greater than or equal to 2GBytes in size
+(2,147,483,648 bytes) :
+- Only files smaller than 2GBytes will be copied; any larger files will be skipped and
+processing will continue with the next file.
+- If at least one file is smaller than 2GBytes, then KErrNone will be returned.
+- If all files are greater than or equal to 2GBytes ,then KErrTooBig will be returned.
+
+One way to detect the presence of any large file(s) is to use an observer: calling
+CFileBase::GetLastError() from MFileManObserver::NotifyFileManEnded() will return
+KErrToBig for any file >= 2GBytes in size.
+
+Note: the copy operation behaves differently when MFileManObserver is used.
+MFileManObserver should be used with multiple files as it enables you to capture the results of all file copy operations.
+
+If MFileManObserver is NOT used then only the result of the last
+file copy operation is returned because the results of previous file copy operations are overwritten.
+
+Optionally, this function can be set to overwrite any files with the same name
+which exist in the target directory. If the flag is set for no overwriting,
+then any files with the same name will not be overwritten, and an error
+(KErrAlreadyExists) will be returned for that file. Error codes may be retrieved
+using CFileBase::GetLastError().
+
+If recursive operation is set, all intermediate directories will be created,
+including any directories in the path specified by aNew which do not
+already exist.
+
+If recursive operation is not set, only the matching files located in
+the single directory specified in anOld are copied.
+No intermediate directories will be created; if any directories in
+the destination path do not exist, no files will be copied, and this function
+will return KErrPathNotFound.
+
+ Notes:
+ 1.	This function operates on files only, therefore:
+ 1.1	In contrast to the way CFileMan::Move() and CFileMan::Rename()
+ 	behave, the behaviour of the copy operation does not depend on the presence
+ 	or absence of a trailing backslash ("\") character. Therefore it is only
+ 	possible to copy the content of the source path. It is NOT
+ 	possible by use of a trailing backslash ("\") character to request that the
+ 	last directory level plus its content be copied to the target path.
+
+ 	This means that the following two example copy operations will behave
+ 	identically
+
+ 	@code
+ 	CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+ 	...
+ 	fm->Copy(_L("C:\\SRC\\"), _L("C:\\TRG\\"), CFileMan::ERecurse);
+ 	fm->Copy(_L("C:\\SRC"), _L("C:\\TRG\\"), CFileMan::ERecurse);
+ 	@endcode
+
+ 	because they will be interpreted as follows:
+ 	@code
+ 	fm->Copy(_L("C:\\SRC\\*"),_L("C:\\TRG\\"), CFileMan::ERecurse);
+ 	@endcode
+
+ 1.2	If there is no file to operate on i.e. if source directory is empty, the
+ 	function will do nothing and return error code KErrNotFound.
+
+ 2. Files can be copied across drives.
+
+ 3. Open files can be copied if they have been opened using
+      the EFileShareReadersOnly file share mode.
+
+ 4. Read-only, hidden and system files can be copied and
+   the source file's attributes are preserved in the target file.
+
+@param anOld     Path indicating the file(s) to be copied.
+                 Any path components which are not specified here will be
+                 taken from the session path.
+@param aNew      Path indicating the directory into which the file(s) are to be copied.
+				 Any path components which are not specified here will be
+                 taken from the session path
+@param aSwitches Specify zero for no overwriting and no recursion;
+                 CFileMan::EOverWrite to overwrite files with the same name;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function operates
+                 non-recursively and with overwriting.
+
+@return KErrNone if successful, KErrNotFound if source directory is empty, otherwise one of the other system-wide error codes.
+
+@see CFileBase::GetLastError()
+
+@capability AllFiles
+
+@capability Dependent If the path for anOld begins with /Sys then Tcb capability is required.
+@capability Dependent If the path for anOld begins with /Resource then Tcb capability is required
+
+*/
+	{
+	TRACEMULT4(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy2, MODULEUID, (TUint) this, anOld, aNew, aSwitches);
+
+	if (iSwitches&KFManBusyFlag)
+		{
+		TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy2Return, MODULEUID, KErrInUse);
+		return(KErrInUse);
+		}
+	SetFlags(aSwitches&EOverWrite,aSwitches&ERecurse,ETrue,EFalse);
+	RETURNIFERRORD(r,iFs.Parse(anOld,iSrcFile),UTraceModuleEfsrv::ECFileManCopy2Return);
+	RETURNIFERROR(r,iFs.Parse(aNew,_L("*"),iTrgFile),UTraceModuleEfsrv::ECFileManCopy2Return);
+	CheckForDirectory();
+
+	if((iSwitches&KRecurseFlag) && iTrgFile.DriveAndPath().MatchF(iSrcFile.FullName()) != KErrNotFound)
+		{
+		TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy2Return, MODULEUID, KErrArgument);
+		return(KErrArgument);
+		}
+
+	iAction = EInternalCopy;
+	iMatchEntry=KEntryAttMaskSupported;
+	iNumberOfFilesProcessed = 0;
+	TRAP(r,RunL());
+	TInt ret=(r==KErrNone) ? iLastError : r;
+	DoSynchronize(r);
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy2Return, MODULEUID, ret);
+	return(ret);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Delete(const TDesC& aName,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Deletes one or more files.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param aName     Path indicating the file(s) to be deleted.
+                 May either be a full path, or relative to the session path.
+                 Use wildcards to specify more than one file.
+                 NOTE: if you pass KNullDesC, the empty (or null) descriptor,
+                 then the function interprets this to mean \\*.*
+@param aSwitches Specify:
+                 zero for no recursion;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function
+                 operates non-recursively.
+@param aStatus   The request status object. On request completion,
+                 indicates how the request completed:
+                 KErrNone, if successful, otherwise one of the other system-wide error
+                 codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability Dependent If aName is /Sys then Tcb capability is required.
+@capability Dependent If aName begins with /Private and does not match this process' SID
+					  then AllFiles capability is required.
+@capability Dependent If aName is /Resource then Tcb capability is required.
+
+@see KNullDesC
+*/
+	{
+	TRACEMULT4(UTF::EBorder, UTraceModuleEfsrv::ECFileManDelete1, MODULEUID, (TUint) this, aName, aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = Delete(aName,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManDelete1Return, MODULEUID, r);
+	return(r);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Delete(const TDesC& aName,TUint aSwitches)
+/**
+Deletes one or more files.
+
+This is a synchronous function.
+
+This function can operate recursively or non-recursively.
+When operating non-recursively, only the matching files located in
+the directory specified in aName are affected.
+When operating recursively, all matching files in the directory hierarchy
+below the directory specified in aName will be deleted.
+
+Note that read-only and open files may not be deleted.
+Attempting to do so will return an error for that file.
+Error codes may be retrieved using CFileBase::GetLastError().
+
+@param aName     Path indicating the file(s) to be deleted.
+                 May either be a full path, or relative to the session path.
+                 Use wildcards to specify more than one file.
+                 NOTE: if you pass KNullDesC, the empty (or null) descriptor,
+                 then the function interprets this to mean \\*.*
+@param aSwitches Specify:
+                 zero for no recursion;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function
+                 operates non-recursively.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+        codes.
+
+@see CFileBase::GetLastError()
+
+@capability Dependent If aName is /Sys then Tcb capability is required.
+@capability Dependent If aName begins with /Private and does not match this process' SID
+					  then AllFiles capability is required.
+@capability Dependent If aName is /Resource then Tcb capability is required.
+
+@see KNullDesC
+*/
+	{
+	TRACEMULT3(UTF::EBorder, UTraceModuleEfsrv::ECFileManDelete2, MODULEUID, (TUint) this, aName, aSwitches);
+
+	TInt ret;
+	if (iSwitches&KFManBusyFlag)
+		{
+		ret = KErrInUse;
+		}
+	else
+		{
+		SetFlags(aSwitches&EOverWrite,aSwitches&ERecurse,ETrue,EFalse);
+		RETURNIFERRORD(r,iFs.Parse(aName,iSrcFile),UTraceModuleEfsrv::ECFileManDelete2Return);
+		iAction = EInternalDelete;
+		iMatchEntry=KEntryAttHidden|KEntryAttMatchExclude|KEntryAttDir;
+	//	Exclude directories and system files - include hidden files
+		iNumberOfFilesProcessed = 0;
+		TRAP(r,RunL());
+		ret=(r==KErrNone) ? iLastError : r;
+		DoSynchronize(r);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManDelete2Return, MODULEUID, ret);
+	return(ret);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Move(const TDesC& anOld,const TDesC& aNew,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Moves one or more files.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param anOld     Path indicating the files to be moved. May be either
+                 a full path, or relative to the session path. Any path
+				 components which are not specified here will be taken
+				 from the session path.
+@param aNew      Path indicating the directory into which the file(s) are
+                 to be moved. Any path components which are not specified
+                 here will be taken from the session path.
+@param aSwitches Specify zero for no overwriting and no recursion;
+                 CFileMan::EOverWrite to overwrite files with the same name;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function operates
+                 non-recursively and with overwriting.
+@param aStatus   The request status object. On request completion,
+                 indicates how the request completed:
+                 KErrNone, if successful, otherwise one of the other system-wide error
+                 codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability Dependent If the path in aNew starts with /Sys then capability Tcb is required
+@capability Dependent If the path in aNew starts with /Resource then capability Tcb is required
+
+@capability AllFiles
+
+@capability Dependent If the path in anOld starts with /Sys then Tcb capability is required.
+@capability Dependent If the path in anOld starts with /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT5(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove1, MODULEUID,
+		(TUint) this, anOld, aNew, aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = Move(anOld,aNew,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove1Return, MODULEUID, r);
+	return r;
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Move(const TDesC& anOld,const TDesC& aNew,TUint aSwitches)
+/**
+Moves one or more files.
+
+This is a synchronous function.
+
+Optionally, this function can be set to overwrite any files with the same name
+which exist in the target directory. If the flag is set for no overwriting,
+then any files with the same name will not be overwritten, and
+an error (KErrAlreadyExists) will be returned for that file.
+Error codes may be retrieved using CFileBase::GetLastError().
+By default, when the function is operating synchronously, files are overwritten.
+
+When this function is operating recursively, all intermediate directories will
+be created, including all directories in the destination path specified
+by aNew which do not already exist.
+
+If recursive operation is not set, only the matching files located in
+the single directory specified in anOld are moved. No intermediate directories
+will be created; if any directories in the destination path do not exist,
+no files will be moved, and this function will return KErrPathNotFound.
+
+The behaviour of the move operation is sensitive to the presence (or absence)
+of a trailing backslash ("\") character on the end of the source path:
+- if there is a trailing backslash ("\") character, then the operation moves
+  the content of the last directory level only.
+- if there is no trailing backslash ("\") character, then the operation behaves
+  recursively by default and moves both the last directory level and all of its content.
+  Notice that no trailing backslash ("\") implies moving files recursively automatically.
+
+For example, if the directory level "b" contains the files F1,F2 and F3, then:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Move(_L("C:\\a\\b\\"), _L("C:\\x\\y\\"), CFileMan::ERecurse);
+@endcode
+
+results in files F1, F2 and F3 being moved from C:\\a\\b to C:\\x\\y, leaving the
+path C:\\a\\b unchanged, except that it no longer contains the files
+F1, F2 and F3.
+
+If there is no trailing backslash character, for example:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Move(_L("C:\\a\\b"), _L("C:\\x\\y\\"), CFileMan::ERecurse);
+@endcode
+
+then both the directory level "b" and its contents are moved. This means that
+there is no longer a directory "b" under C:\\a. Instead there is a new
+directory structure C:\\x\\y\\b and the files F1, F2, and F3 now exist
+under C:\\x\\y\\b. Also if "b" contains subdirectories, then these are also
+moved along with "b".
+
+If there is no trailing backslash character and the switch is not set, i.e.
+0 is passed as an argument, the operation behaves the same way as by passing
+CFileMan::ERecurse flag.
+
+for example:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Move(_L("C:\\a\\b"), _L("C:\\x\\y\\"), 0);
+@endcode
+
+The example above produces the same output as:
+
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Move(_L("C:\\a\\b"), _L("C:\\x\\y\\"), CFileMan::ERecurse);
+@endcode
+
+Notes:
+
+-# Read-only, hidden and system files can be moved and the source file's
+   attributes are preserved in the target file, but open files cannot
+   be moved. Attempting to move an open file will return an error for
+   that file, as retrieved by CFileBase::GetLastError().
+
+@param anOld	 Path indicating the files to be moved. May be either a full path, or
+				 relative to the session path. Note that if you specify a directory level,
+				 then the behaviour of the move operation is sensitive to the presence
+				 (or absence) of a trailing backslash ("\") character. Any path components
+				 which are not specified here will be taken from the session path. See the
+				 main description for the detailed explanation.
+@param aNew      Path indicating the directory into which the file(s) are to be moved.
+				 Any path components which are not specified here will be taken from the session path.
+@param aSwitches CFileMan::EOverWrite to overwrite files with the same name;
+                 CFileMan::ERecurse for recursion.
+                 By default, the synchronous variant of this function operates non-recursively and
+				 with overwriting. And no trailing backslash ("\") character at the end of source path
+				 always means CFileMan::ERecurse.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+        codes.
+
+@capability Dependent If the path in aNew starts with /Sys then capability Tcb is required
+@capability Dependent If the path in aNew starts with /Resource then capability Tcb is required
+
+@capability AllFiles
+
+@capability Dependent If the path in anOld starts with /Sys then Tcb capability is required.
+@capability Dependent If the path in anOld starts with /Resource then Tcb capability is required.
+
+@see CFileBase::GetLastError()
+*/
+	{
+	TRACEMULT4(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove2, MODULEUID,
+		(TUint) this, anOld, aNew, aSwitches);
+
+
+	if (iSwitches&KFManBusyFlag)
+		{
+		TRACE1(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove2Return, MODULEUID, KErrInUse);
+		return(KErrInUse);
+		}
+
+	iNumberOfFilesProcessed = 0;
+
+	RETURNIFERRORD(r,iFs.Parse(anOld,iSrcFile),UTraceModuleEfsrv::ECFileManMove2Return);
+	RETURNIFERROR(r,iFs.Parse(aNew,_L("*"),iTrgFile),UTraceModuleEfsrv::ECFileManMove2Return);
+
+	TInt ret = KErrNone;
+	TBool aComplete = EFalse;
+	if(SrcTrgDrivesIdentical())
+		{
+		ret = SetupMoveOnSameDrive(aSwitches, aComplete);
+		}
+	else
+		{
+		ret = SetupMoveAcrossDrives(aSwitches);
+		}
+
+	if(ret != KErrNone || aComplete)
+		{
+		if (iStatus)
+			{
+			User::RequestComplete(iStatus, ret);
+			}
+		TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove2Return, MODULEUID, ret);
+		return(ret);
+		}
+
+	iMatchEntry = KEntryAttMaskSupported;
+	if((aSwitches&ERecurse)==0 && iMovingContents)
+		{
+		iMatchEntry = KMovingFilesMask;
+		}
+
+	// Do the Move or Rename Operation
+	TRAP(r,RunL());
+	ret = (r==KErrNone) ? iLastError : r;
+	DoSynchronize(r);
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManMove2Return, MODULEUID, ret);
+	return(ret);
+	}
+
+
+TBool CFileMan::SrcTrgDrivesIdentical()
+//
+// Returns ETrue if the source and target drives are the same
+//	- Used by CFileMan::Move operations to determine whether to rename or move the files
+//
+	{
+	return iSrcFile.Drive().MatchF(iTrgFile.Drive()) != KErrNotFound;
+	}
+
+
+TInt CFileMan::SetupDirectoryForMove(TBool& aSrcIsDir)
+/**
+ * Sets up the target specification to include the new target directory if required.
+ * 
+ * @param aSrcIsDir	Set to ETrue if the source specifies that the directory is to be moved in its entirety,
+ * 					or EFalse if only the contents of the directory need to be moved.
+ * 
+ * @return KErrNone if successful, otherwise one of the system wide error codes.
+ */
+	{
+	iMovingContents = ETrue;
+	aSrcIsDir = EFalse;
+	
+	TPtrC nameAndExt(iSrcFile.NameAndExt());
+	if (nameAndExt == _L("*") || nameAndExt == _L("*.*"))
+		{
+		// Wildcard specification - Move the entire contents of the directory to the target
+		aSrcIsDir = ETrue;
+		}
+	else
+		{
+		TInt src = iFs.Entry(iSrcFile.FullName(), iTmpEntry);
+		if ((src == KErrNone && iTmpEntry.iAtt&KEntryAttDir) || (!iSrcFile.NamePresent() && iSrcFile.IsRoot()))
+			{
+			aSrcIsDir = ETrue;
+
+			// A directory is specified.
+			//  - Mandatory recursion with Wildcard Copy
+			//	- Target is a directory (Enforced by MakeParseWild)
+
+			MakeParseWild(iTrgFile, iTmpName1);
+
+			// Construct the target name by parsing
+			// the source path for the directory name.
+			TPtrC srcPath(iSrcFile.FullName());
+			TInt srcPathLen = srcPath.Length() - 1;
+
+			iMovingContents = (srcPath[srcPathLen] == KPathDelimiter);	// Moving the directory itself, or the contents?
+
+			if(!iMovingContents)
+				{
+				// No path delimiter specified
+				//	- move the whole directory (if specified)
+				TInt len = srcPath.Length();
+
+				TInt idx = srcPath.Left(len).LocateReverse(KPathDelimiter);
+
+				if((idx >= 2) && (idx != KErrNotFound))
+					{
+					// Source path is a directory (not just the drive)
+					TPtrC mid(srcPath.Left(len).Mid(1+idx));
+					TInt r = iTrgFile.AddDir(mid);
+					if (r != KErrNone)
+						return r;
+					}
+				}
+			}
+		}
+
+	return KErrNone;
+	}
+
+
+TInt CFileMan::SetupTargetDirectory(TBool aOverWrite, TBool& aComplete)
+	{
+	aComplete = EFalse;
+
+	TInt trgErr = iFs.Entry(iTrgFile.DriveAndPath(), iTmpEntry);
+
+	TEntry srcEntry;
+	TInt srcErr = iFs.Entry(iSrcFile.FullName(), srcEntry);
+
+	if(srcErr == KErrNone && trgErr == KErrNone)
+		{
+        if ((srcEntry.iAtt&KEntryAttDir) != (iTmpEntry.iAtt&KEntryAttDir))
+        	{
+        	// return KErrAccessDenied if it is trying to overwrite a file to a dir or vice versa.
+        	return KErrAccessDenied;
+        	}
+		}
+
+	if(trgErr == KErrNone)
+		{
+		// Already Exists - Overwrite if flags set
+		if(!aOverWrite)
+			{
+			trgErr = KErrAlreadyExists;
+			}
+		else
+			{
+			iNumberOfFilesProcessed++;
+			}
+		}
+	else if((trgErr == KErrNotFound) || (trgErr == KErrPathNotFound))
+		{
+		if(SrcTrgDrivesIdentical())
+			{
+			// When moving a directory on the same drive, the directory can simply be renamed...
+			TParse& midDir = iTmpParse;
+			midDir = iTrgFile;
+			if(midDir.PopDir() == KErrNone)
+				{
+				// ...before renaming, ensure that all intermediate directories exist
+				trgErr = iFs.MkDirAll(midDir.DriveAndPath());
+				if(trgErr == KErrAlreadyExists)
+					{
+					trgErr = KErrNone;
+					}
+				}
+
+			if (trgErr == KErrNone)
+				{
+				// ...and finally rename the source directory
+				trgErr = iFs.Rename(iSrcFile.FullName(),iTrgFile.DriveAndPath());
+				aComplete = ETrue;
+				}
+			}
+		else
+			{
+			trgErr = iFs.MkDirAll(iTrgFile.FullName());
+			}
+		iNumberOfFilesProcessed++;
+		}
+
+	return(trgErr);
+	}
+
+
+TInt CFileMan::SetupMoveOnSameDrive(TUint aSwitches, TBool& aComplete)
+	{
+	// Moving on the same drive.
+
+	aComplete = EFalse;
+
+	TBool srcIsDir = EFalse;
+    TInt ret = SetupDirectoryForMove(srcIsDir);
+    if (ret != KErrNone)
+		{
+        return ret;
+		}
+
+	TBool scanDown = ETrue;
+	TBool recurse = (aSwitches & ERecurse);
+
+	iAction = EInternalRenameForMove;
+
+	TFileName& srcpath = iTmpName1;
+	srcpath.Copy(iSrcFile.FullName());
+	if(srcpath.Length()<KMaxFileName && srcpath.Length()>1 && srcpath[srcpath.Length()-1]!=KPathDelimiter)
+		{
+		srcpath.Append(KPathDelimiter);
+		}
+
+	// If the source path is a subset of the target path then Move operation is not allowed
+	if((srcIsDir && recurse) || (srcIsDir && !iTrgFile.IsRoot() && !iMovingContents))
+		{
+		if(iTrgFile.FullName().Left(srcpath.Length()).MatchF(srcpath)==0)
+			{
+			aComplete = ETrue;
+			return KErrInUse;
+			}
+		}
+	// if any of the SRC folders already existing in TRG, scan upwards
+	if(iMovingContents)
+		{
+		CDirScan* srcScanDir = NULL;
+		CDirScan* trgScanDir = NULL;
+		CDir* srcEntryList = NULL;
+		CDir* trgEntryList = NULL;
+		TInt trgCnt = 0;
+		TInt srcCnt = 0;
+
+		TRAP(ret,(srcScanDir = CDirScan::NewL(iFs)));
+		if (ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		TRAP(ret,srcScanDir->SetScanDataL(iSrcFile.FullName(),KEntryAttMaskSupported,ESortByName));
+		if (ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		TRAP(ret,srcScanDir->NextL(srcEntryList));
+		if(ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		TRAP(ret,(trgScanDir=CDirScan::NewL(iFs)));
+		if (ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		TRAP(ret,trgScanDir->SetScanDataL(iTrgFile.FullName(),KEntryAttMaskSupported,ESortByName));
+		if (ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		TRAP(ret,trgScanDir->NextL(trgEntryList));
+		if(ret!=KErrNone)
+			{
+			goto CleanUp;
+			}
+		for(trgCnt=trgEntryList->Count()-1; trgCnt>-1; trgCnt--)
+			{
+			for(srcCnt=srcEntryList->Count()-1; srcCnt>-1; srcCnt--)
+				{
+				if( (*srcEntryList)[srcCnt].iName == (*trgEntryList)[trgCnt].iName
+					&& ((*srcEntryList)[srcCnt].iAtt & KEntryAttDir)
+					&& ((*trgEntryList)[trgCnt].iAtt & KEntryAttDir))
+					{
+					// Set scan upwards
+					scanDown = EFalse;
+					goto CleanUp;
+					}
+				}// end inner for loop
+			} // end outer for loop
+CleanUp:
+		// clean up
+		if(srcEntryList!=NULL)
+			delete srcEntryList;
+		if(trgEntryList!=NULL)
+			delete trgEntryList;
+		if(srcScanDir!=NULL)
+			delete srcScanDir;
+		if(trgScanDir!=NULL)
+			delete trgScanDir;
+		}// end if(iMovingContents)
+
+	if(srcIsDir && !iTrgFile.IsRoot() && !iMovingContents)
+		{
+		ret = SetupTargetDirectory(aSwitches & EOverWrite, aComplete);
+		if(ret != KErrNone || aComplete)
+			{
+			return(ret);
+			}
+		}
+	if(!iMovingContents)
+		{
+		recurse = ETrue;
+		scanDown = EFalse;
+		}
+	if(srcIsDir)
+		{
+		MakeParseWild(iSrcFile, iTmpName1);
+		}
+
+	SetFlags(aSwitches & EOverWrite, recurse, scanDown, ETrue);
+	return(KErrNone);
+	}
+
+
+TInt CFileMan::SetupMoveAcrossDrives(TUint aSwitches)
+	{
+	// Moving across drives.  We may need to recurse,
+	// depending on the supplied source path.
+
+	TBool srcIsDir = EFalse;
+    TInt ret = SetupDirectoryForMove(srcIsDir);
+    if (ret != KErrNone)
+		{
+        return ret;
+		}
+    
+	TBool recurse = (aSwitches & ERecurse);
+	TBool scanDown = (recurse) ? (TBool)EFalse : (TBool)ETrue;
+
+	if(srcIsDir)
+		{
+		if(!iMovingContents)
+			{
+			recurse = ETrue;
+			if(!iTrgFile.IsRoot())
+				{
+				TBool complete = EFalse;
+				ret = SetupTargetDirectory(aSwitches & EOverWrite, complete);
+				if(ret != KErrNone || complete)
+					{
+					return(ret);
+					}
+				}
+			}
+		}
+
+	CheckForDirectory();
+	iAction = EInternalCopyForMove;
+	SetFlags(aSwitches & EOverWrite, recurse, scanDown, EFalse);
+	return(KErrNone);
+	}
+
+TInt CFileMan::RenameInvalidEntry(const TDesC& /*aName*/,const TDesC& /*aNewName*/,TUint /*aSwitches*/)
+//
+// Start rename operation
+//
+	{
+	return KErrNotSupported;
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Rename(const TDesC& aName,const TDesC& aNewName,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Renames one or more files.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param aName     Path specifying the file(s) to be renamed. Any path components
+				 which are not specified
+                 here will be taken from the session path.
+@param aNewName  Path specifying the new name for the files and/or
+                 the new directory. Any directories specified in this path
+                 that do not exist, will be created. Any path components
+				 which are not specified here will be taken from the session path.
+@param aSwitches Specify zero for no overwriting;
+                 CFileMan::EOverWrite to overwrite files with the same name.
+                 This function cannot operate recursively.
+@param aStatus   The request status object. On request completion,
+                 indicates how the request completed:
+                 KErrNone, if successful, otherwise one of the other system-wide error
+                 codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability Dependent If either aName or aNewName is /Sys then Tcb capability is required.
+@capability Dependent If either aName or aNewName begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If either aName or aNewName is /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT5(UTF::EBorder, UTraceModuleEfsrv::ECFileManRename1, MODULEUID,
+		(TUint) this, aName, aNewName, aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = Rename(aName,aNewName,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManRename1Return, MODULEUID, r);
+	return(r);
+	}
+
+
+
+
+EXPORT_C TInt CFileMan::Rename(const TDesC& aName,const TDesC& aNewName,TUint aSwitches)
+/**
+Renames one or more files, or a directory
+
+This is a synchronous function.
+
+The function can also be used to move files by specifying different destination
+and source directories.
+
+Some rules for using CFileMan::Rename():
+
+1. General rules:
+
+1.1. Trailing backslash ("\") in either source path (aName) or target path (aNewName)
+will be interpreted to "\*.*";
+
+For example, following code should behave identically:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC\\"), _L("C:\\TRG\\"));
+fm->Rename(_L("C:\\SRC\\*.*"), _L("C:\\TRG\\"));
+fm->Rename(_L("C:\\SRC\\"), _L("C:\\TRG\\*.*"));
+fm->Rename(_L("C:\\SRC\\*.*"), _L("C:\\TRG\\*.*"));
+@endcode
+
+1.2 The behaviour of the rename operation is sensitive to the presence (or absence) of
+a trailing backslash ("\") character on the end of the target path (aNewName);
+
+For example, under all other constraints (see rules 2. and 3.),
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG\"));
+@endcode
+will result in renaming "C:\\SRC" to "C:\\TRG\\SRC", while
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG"));
+@endcode
+will result in renaming "C:\\SRC" to "C:\\TRG".
+
+2. Renaming file(s):
+
+2.1 Wildcards:
+
+A file's name and extension are interpreted separately, for example:
+
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC\\1234.567"), _L("C:\\TRG\\AB*CD.TXT"));
+@endcode
+renames the source file to file "C:\\TRG\\AB34CD.TXT".
+
+Wildcards can be used for renaming multiple files, for example;
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC\\*.567"), _L("C:\\TRG\\*.TXT"));
+@endcode
+renames all the file under "C:\\SRC\\" having extension ".567" to the files under
+"C:\\TRG\\" having extension ".TXT".
+
+2.2 An option is provided to allow the user to overwrite any files with the same
+name which may exist in the target directory; If the flag is set for no overwriting,
+any files with the same name will not be overwritten, and an error (KErrAlreadyExists)
+will be returned for that file, as retrieved by CFileBase::GetLastError().
+
+2.3 It can only operate non-recursively, so that only the matching files located
+in the single directory specified by anOld may be renamed.
+
+2.4 Trying to rename file(s) to existing directory(ies) will fail;
+
+For example, giving following directory structure:
+@code
+C:\SRC\ITEM01
+C:\SRC\ITEM02
+C:\TRG\ITEM01\
+C:\TRG\ITEM02\
+@endcode
+
+Following code will fail:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC\\ITEM01"), _L("C:\\TRG\\ITEM01"));
+fm->Rename(_L("C:\\SRC\\ITEM*"), _L("C:\\TRG\\ITEM*"));
+fm->Rename(_L("C:\\SRC\\"), _L("C:\\TRG\\"));
+@endcode
+
+3. When renamnig a directory:
+
+3.1. Only when the trailing backslash ("\") is missing from the source path (aName),
+will the source directory be renamed, otherwise, see rule 1.1.
+
+For example, following code will result in moving "C:\SRC" directory including all
+its contents:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG"));
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG\\"));
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG\\*.*"));
+@endcode
+
+3.2. Wildcards can not be used for moving directories;
+
+3.3. Overwriting is not permitted;
+
+For example, giving directory structure as following:
+@code
+C:\SRC\FILE.TXT
+C:\TRG\
+C:\TRG\SRC\
+@endcode
+
+following code will fail:
+@code
+CFileMan* fm(CFileMan::NewL(iFs)); // Where iFs is an RFs handle
+...
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG"));
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG\\"));
+fm->Rename(_L("C:\\SRC"), _L("C:\\TRG\\*.*"));
+@endcode
+
+4. Notes:
+
+4.1. The target and source directories must be on the same drive.
+
+4.2. Read-only, hidden and system files can be moved and the source file's
+attributes are preserved in the target file, but open files cannot
+be moved. Attempting to move an open file will return an error for
+that file, as retrieved by CFileBase::GetLastError().
+
+@param aName     Path specifying the file(s) to be renamed. Any path components
+				 which are not specified
+                 here will be taken from the session path.
+@param aNewName  Path specifying the new name for the files and/or
+                 the new directory. Any directories specified in this path
+                 that do not exist, will be created. Any path components which
+				 are not specified here will be taken from the session path.
+@param aSwitches Specify zero for no overwriting;
+                 CFileMan::EOverWrite to overwrite files with the same name.
+                 This function cannot operate recursively.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+        codes.
+
+@see CFileBase::GetLastError()
+
+@capability Dependent If either aName or aNewName is /Sys then Tcb capability is required.
+@capability Dependent If either aName or aNewName begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If either aName or aNewName is /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT4(UTF::EBorder, UTraceModuleEfsrv::ECFileManRename2, MODULEUID,
+		(TUint) this, aName, aNewName, aSwitches);
+
+	TInt ret;
+	if (iSwitches&KFManBusyFlag)
+		{
+		ret = KErrInUse;
+		}
+	else
+		{
+		SetFlags(aSwitches&EOverWrite,EFalse,ETrue,EFalse);
+		RETURNIFERRORD(r,iFs.Parse(aName,iSrcFile),UTraceModuleEfsrv::ECFileManRename2Return);
+		RETURNIFERROR(r,iFs.Parse(aNewName,_L("*"),iTrgFile),UTraceModuleEfsrv::ECFileManRename2Return);
+
+		iAction = EInternalRename;
+		iMatchEntry=KEntryAttMaskSupported;
+		iNumberOfFilesProcessed = 0;
+		TRAP(r,RunL());
+		ret=(r==KErrNone) ? iLastError : r;
+		DoSynchronize(r);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManRename2Return, MODULEUID, ret);
+	return(ret);
+	}
+
+
+EXPORT_C TInt CFileMan::RmDir(const TDesC& aDirName,TRequestStatus& aStatus)
+/**
+Deletes a directory and all files and directories contained in the
+directory structure below it.
+
+Other than being asynchronous, the behaviour of this function is the same
+as is documented in its synchronous overload.
+
+@param aDirName Path specifying the directory to be deleted. Any path components
+				which are not specified here will be taken from the session path.
+@param aStatus  The request status object. On request completion, indicates how
+                the request completed:
+                KErrNone if successful, otherwise one of the other system-wide
+                error codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@capability Dependent If aDirName starts with /Sys then Tcb capability is required.
+@capability Dependent If aDirName begins with /Private and does not match this process' SID
+					  then AllFiles capability is required.
+@capability Dependent If aDirName starts with /Resource then Tcb capability is required.
+
+*/
+	{
+	TRACEMULT3(UTF::EBorder, UTraceModuleEfsrv::ECFileManRmDir1, MODULEUID, (TUint) this, aDirName, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = RmDir(aDirName);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManRmDir1Return, MODULEUID, r);
+	return r;
+	}
+
+
+EXPORT_C TInt CFileMan::RmDir(const TDesC& aDirName)
+/**
+Deletes a directory and all files and directories contained in the
+directory structure below it.
+
+This is a synchronous function.
+
+The function cannot be used non-recursively. For a non-recursive
+directory deletion, use RFs::RmDir().
+
+Note:
+
+1. All files in the directory hierarchy to be deleted must be closed and
+   none may have the read-only attribute. Otherwise, not all of the hierarchy will
+   be deleted, and this function will return KErrInUse.
+
+@param aDirName Path specifying the directory to be deleted. Any path components
+				which are not specified here will be taken from the session path.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+        codes.
+
+@capability Dependent If aDirName starts with /Sys then Tcb capability is required.
+@capability Dependent If aDirName begins with /Private and does not match this process' SID
+					  then AllFiles capability is required.
+@capability Dependent If aDirName starts with /Resource then Tcb capability is required.
+
+
+*/
+	{
+	TRACEMULT2(UTF::EBorder, UTraceModuleEfsrv::ECFileManRmDir2, MODULEUID, (TUint) this, aDirName);
+
+	TInt ret;
+	if (iSwitches&KFManBusyFlag)
+		{
+		ret = KErrInUse;
+		}
+	else
+		{
+		SetFlags(ETrue,ETrue,EFalse,EFalse);
+		RETURNIFERRORD(r,iFs.Parse(aDirName,iTrgFile),UTraceModuleEfsrv::ECFileManRmDir2Return);
+		iSrcFile.Set(iTrgFile.DriveAndPath(),NULL,NULL);
+		iAction = EInternalRmDir;
+		iMatchEntry=KEntryAttMaskSupported;
+		iNumberOfFilesProcessed = 0;
+		TRAP(r,RunL());
+		DoSynchronize(r);
+		ret = (r!=KErrNone) ? iLastError : KErrNone;
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManRmDir2Return, MODULEUID, ret);
+	return ret;
+	}
+
+
+void CFileMan::DoOperationL()
+// Call the action in progress.
+	{
+	switch (iAction)
+		{
+	case EInternalAttribs:
+		DoAttribsL();
+		break;
+	case EInternalCopy:
+	case EInternalCopyForMove:
+		DoCopyOrMoveL();
+		break;
+	case EInternalDelete:
+		DoDeleteL();
+		break;
+	case EInternalRenameInvalidEntry:
+	case EInternalRenameForMove:
+	case EInternalRename:
+		DoRenameL();
+		break;
+	case EInternalRmDir:
+		DoRmDirL();
+		break;
+	case EInternalCopyFromHandle:
+		DoCopyFromHandleL();
+		break;
+	default:
+		Panic(EFManUnknownAction);
+		}
+	}
+
+void CFileMan::DoAttribsL()
+//
+// Do attribs operation step
+//
+	{
+	TPtrC fullPath(FullPath());
+	iTmpParse.Set(CurrentEntry().iName, &fullPath, NULL);
+	User::LeaveIfError(iFs.SetEntry(iTmpParse.FullName(), iTime, iSetMask, iClearMask));
+	}
+
+void CFileMan::DoCopyOrMoveL()
+//
+// Do copy or move operation
+//
+	{
+	// Following 'if' statements are to prevent incorrect recursive Move() or Copy() from "destination"
+	//  to "destination", this problem occurs when the initial source directory contains destination
+	//  directory.
+	//  (e.g. CFileMan::Move(_L("C:\\SRC\\*.TXT"), _L("C:\\SRC\\Sub\\"), CFileMan::ERecurse);)
+	// Note that CFileMan::Rename() does not suffer from this particular case, as CFileMan::Rename() API
+	//  can only operate non-recursively.
+	if (iSrcFile.DriveAndPath().Length() < iTrgFile.DriveAndPath().Length())
+		{
+		if (iTrgFile.DriveAndPath().Left(iSrcFile.DriveAndPath().Length()) == iSrcFile.DriveAndPath())
+		// If source directory path contains destination directory path, including drive number, we consider
+		//  this is "...\\ROOT\\" -> "...\\ROOT\\SUB\\" type of operation. Therefore skips all the items we
+		//  found in "...\\ROOT\\SUB\\". We achieve this by checking current scanning directory path:
+			{
+			if (iTrgFile.DriveAndPath() == iScanner->FullPath().Left(iTrgFile.DriveAndPath().Length()))
+				{
+				return;
+				}
+			}
+		}
+
+	TParse& srcName = iTmpParse;
+	TFileName& trgName = iTmpName1;
+	GetSrcAndTrg(srcName,trgName);
+
+	// Handle case when source is directory
+	if (CurrentEntry().iAtt&KEntryAttDir)
+		{
+		if(!(iSwitches&KRecurseFlag))
+			{
+			User::Leave(KErrNone);
+			}
+		trgName.Append(KPathDelimiter);
+		TInt r = iFs.MkDirAll(trgName);
+		if (r!=KErrNone && r!=KErrAlreadyExists)
+			User::Leave(r);
+
+		if(iAction == EInternalCopyForMove)
+			{
+			// Move operation - Attempt to delete the source directory.
+			if((iMatchEntry & KMovingFilesMask) != KMovingFilesMask)
+				{
+				iTmpName2 = srcName.FullName();
+				iTmpName2.Append(KPathDelimiter);
+				TInt rdErr = iFs.RmDir(iTmpName2);
+				if(rdErr != KErrNone && rdErr != KErrInUse)
+					{
+					User::Leave(rdErr);
+					}
+				}
+			}
+		return;
+		}
+
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+	RFile srcFile,trgFile;
+#else
+	RFile64 srcFile,trgFile;
+#endif
+	TInt r=KErrNone;
+	if (FileNamesIdentical(srcName.FullName(),trgName))
+		{
+		if (iSwitches & KOverWriteFlag)
+			// Source and target are identical, KOverWriteFlag makes copying
+			// having no effect.
+			return;
+		else
+			User::Leave(KErrAlreadyExists);
+		}
+
+	r=srcFile.Open(iFs, srcName.FullName(),
+	                iAction==EInternalCopy ? EFileRead|EFileShareReadersOnly  // Copy access
+	                                : EFileWrite|EFileWriteDirectIO|EFileShareExclusive); // Move access
+	TBool isRO = EFalse;
+	if(r==KErrAccessDenied && iAction==EInternalCopyForMove)
+		{
+		TEntry& entry = iTmpEntry;
+		r = iFs.Entry(srcName.FullName(), entry);
+		if(r==KErrNone && (entry.iAtt&KEntryAttReadOnly))
+			{
+			isRO = ETrue;
+			r = iFs.SetAtt(srcName.FullName(), 0, KEntryAttReadOnly);
+			if(r==KErrNone)
+				{
+				r = srcFile.Open(iFs, srcName.FullName(), EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+				}
+			}
+		}
+	if (r!=KErrNone)
+		{
+		iErrorInfo=ESrcOpenFailed;
+		if(isRO)
+			{
+			iFs.SetAtt(srcName.FullName(), KEntryAttReadOnly, 0);
+			}
+		User::Leave(r);
+		}
+
+	if ((iSwitches&KOverWriteFlag)==0)
+		r=trgFile.Create(iFs,trgName,EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+	else
+		r=trgFile.Replace(iFs,trgName,EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+
+	if (r==KErrPathNotFound && (iSwitches&KRecurseFlag))
+		{
+		r=iFs.MkDirAll(trgName);
+		if (r==KErrNone)
+			r=trgFile.Create(iFs,trgName,EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+		}
+
+	if (r!=KErrNone)
+		iErrorInfo=ETrgOpenFailed;
+
+	TInt ret=0;
+	if (r == KErrNone)
+		r = DoCopy(srcFile, trgFile, ret);
+
+	srcFile.Close();
+	trgFile.Close();
+	if ((r!=KErrNone && (r!=KErrAlreadyExists && iErrorInfo!=ETrgOpenFailed)) || (ret==MFileManObserver::ECancel))
+		iFs.Delete(trgName);
+	if(r==KErrNone && isRO)
+		{
+		r = iFs.SetAtt(trgName, KEntryAttReadOnly, 0);
+		}
+	User::LeaveIfError(r);
+
+	//
+	// Move operation
+	//
+	if (iAction == EInternalCopyForMove && ret != MFileManObserver::ECancel)
+		{
+		r=iFs.Delete(srcName.FullName());
+		if (r==KErrNone)
+			return;
+		iFs.Delete(trgName);
+		User::Leave(r);
+		}
+	}
+
+void CFileMan::DoDeleteL()
+//
+// Do delete operation step
+//
+	{
+	TFileName& pathname = iTmpName1;
+	TFileName& filename = iTmpName2;
+	pathname.Copy(FullPath());
+	filename.Copy(CurrentEntry().iName);
+	if(CurrentEntry().iName.Length() + pathname.Length() > KMaxFileName)
+		{
+		User::LeaveIfError(ShrinkNames(iFs, pathname, filename, EFalse));
+		}
+	iTmpParse.Set(filename, &pathname, NULL);
+	User::LeaveIfError(iFs.Delete(iTmpParse.FullName()));
+	}
+
+void CFileMan::DoRenameL()
+//
+// Do rename operation step
+//
+	{
+	// Following 'if' statements are to prevent incorrect recursive Move() or Copy() from "destination"
+	//  to "destination", this problem occurs when the initial source directory contains destination
+	//  directory.
+	//  (e.g. CFileMan::Move(_L("C:\\SRC\\*.TXT"), _L("C:\\SRC\\Sub\\"), CFileMan::ERecurse);)
+	// Note that CFileMan::Rename() does not suffer from this particular case, as CFileMan::Rename() API
+	//  can only operate non-recursively.
+	if (iSrcFile.DriveAndPath().Length() < iTrgFile.DriveAndPath().Length())
+		{
+		if (iTrgFile.DriveAndPath().Left(iSrcFile.DriveAndPath().Length()) == iSrcFile.DriveAndPath())
+		// If source directory path contains destination directory path, including drive number, we consider
+		//  this is "...\\ROOT\\" -> "...\\ROOT\\SUB\\" type of operation. Therefore skips all the items we
+		//  found in "...\\ROOT\\SUB\\". We achieve this by checking current scanning directory path:
+			{
+			if (iTrgFile.DriveAndPath() == iScanner->FullPath().Left(iTrgFile.DriveAndPath().Length()))
+				{
+				return;
+				}
+			}
+		}
+
+	TParse& srcName = iTmpParse;
+	TFileName& trgName = iTmpName1;
+	GetSrcAndTrg(srcName, trgName);
+
+	TInt r = iFs.Rename(srcName.FullName(),trgName);
+	if (r==KErrAlreadyExists && (iSwitches&KOverWriteFlag)!=0)
+		{
+		// Target already exists, with the overwrite flag enabled
+		if((CurrentEntry().iAtt & KEntryAttDir) == 0)
+			{
+			// Renaming a file
+			r=iFs.Replace(srcName.FullName(),trgName);
+			}
+		else if (iAction == EInternalRenameForMove)
+			{
+			trgName = srcName.FullName();
+			trgName.Append(KPathDelimiter);
+			r = iFs.RmDir(trgName); // remove empty directory after move
+			if(r == KErrInUse)
+				{
+				r = KErrNone;
+				}
+			}
+		}
+
+	if (r==KErrPathNotFound)
+		{
+		if((iSwitches&KMoveRenameFlag) && !(iSwitches&KRecurseFlag))
+			User::Leave(r);
+		r=iFs.MkDirAll(trgName);
+		if (r==KErrNone)
+			 r=iFs.Rename(srcName.FullName(),trgName);
+		}
+	if (r==KErrBadName)
+		{
+		TEntry& entry = iTmpEntry;
+		TInt retcode=iFs.Entry(srcName.FullName(), entry);
+		if (retcode!=KErrNone)
+			iErrorInfo=ESrcOpenFailed;
+		else
+			iErrorInfo=ETrgOpenFailed;
+		}
+	User::LeaveIfError(r);
+	}
+
+void CFileMan::DoRmDirL()
+//
+// Do rmdir operation step
+//
+	{
+	TFileName& srcName = iTmpName1;
+	srcName.Copy(FullPath());
+	if (srcName.Length() + CurrentEntry().iName.Length() > KMaxFileName)
+		{
+		TFileName& current = iTmpName2;
+		current.Copy(CurrentEntry().iName);
+		User::LeaveIfError(ShrinkNames(iFs, srcName, current, ETrue));
+		}
+	else
+		{
+		srcName.Append(CurrentEntry().iName);
+		}
+
+	if ((CurrentEntry().iAtt&KEntryAttDir)==0)
+		User::LeaveIfError(iFs.Delete(srcName));
+	else
+		{
+		srcName.Append(KPathDelimiter);
+		User::LeaveIfError(iFs.RmDir(srcName));
+		}
+	}
+
+
+void CFileMan::CompleteOperationL()
+//
+// Tidy up after an operation
+// The last step to remove directory or to a move directory operation
+// is to remove the source directory...
+//
+	{
+	TInt r=KErrNotFound;
+	if (iAction == EInternalRmDir ||
+	    (iAction == EInternalCopyForMove && ((iMatchEntry & KMovingFilesMask) != KMovingFilesMask) && !iMovingContents && !iSrcFile.IsRoot()) ||
+	    iAction == EInternalRenameForMove && !iMovingContents && iNumberOfFilesProcessed)
+		{
+		r=iFs.RmDir(iSrcFile.FullName());
+		if ((r!=KErrNone && r!=KErrNotFound && iAction!=EInternalRenameForMove && r!=KErrInUse) || (iAction == EInternalRmDir && r == KErrInUse))
+			{
+			iLastError=r;
+			User::Leave(r);
+			}
+		}
+
+	if (iLastError == KErrCancel && iNumberOfFilesProcessed==0 )
+	{
+		iLastError=KErrCancel;
+		iErrorInfo=ENoFilesProcessed;
+		User::Leave(KErrCancel);
+	}
+
+	if (iLastError==KErrNone && r==KErrNotFound && iNumberOfFilesProcessed==0)
+		{
+		iLastError=KErrNotFound;
+		iErrorInfo=ENoFilesProcessed;
+		User::Leave(KErrNotFound);
+		}
+	}
+
+void CFileMan::SetFlags(TBool anOverWrite,TBool aRecurse,TBool aScanDownTree,TBool aMoveRename)
+//
+// Set or clear flags
+//
+	{
+
+	iSwitches=0;
+	if (aRecurse)
+		iSwitches|=KRecurseFlag;
+	if (anOverWrite)
+		iSwitches|=KOverWriteFlag;
+	if (aScanDownTree)
+		iSwitches|=KScanDownFlag;
+	if (aMoveRename)
+		iSwitches|=KMoveRenameFlag;
+	}
+
+
+EXPORT_C TInt CFileMan::Copy(const RFile& anOld, const TDesC& aNew, TUint aSwitches)
+/**
+Copies from an open file handle to a destination file name.
+
+This is a synchronous function.
+
+Optionally, this function can be set to overwrite the target file.
+If the flag is set for no overwriting and the target file already exists,
+then the target file will not be overwritten, and an error (KErrAlreadyExists)
+will be returned.
+Error codes may be retrieved using CFileBase::GetLastError().
+
+Notes:
+
+-# The file can be copied across drives.
+-# Read-only, hidden and system files can be copied and
+   the source file's attributes are preserved in the target file.
+
+@param anOld     Open file handle indicating the file to be copied.
+@param aNew      Path indicating the directory (and optionally the filename)
+				 into which the file is to be copied.
+				 Any path components which are not specified here will be
+                 taken from the session path
+@param aSwitches Specify zero for no overwriting;
+                 CFileMan::EOverWrite to overwrite files with the same name;
+                 Any other flags are illegal
+                 By default, the synchronous variant of this function operates
+                 with overwriting.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+
+@see CFileBase::GetLastError()
+@see CFileMan::Move()
+
+@capability Dependent If the path for aNew begins with /Sys then Tcb capability is required.
+@capability Dependent If the path for aNew begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If the path for aNew begins with /Resource then Tcb capability is required.
+*/
+	{
+	TRACEMULT4(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy3, MODULEUID,
+		(TUint) this, anOld.SubSessionHandle(), aNew, aSwitches);
+
+	TInt ret;
+	if (iSwitches&KFManBusyFlag)
+		{
+		ret = KErrInUse;
+		}
+		// The only switch that is legal for single file copies is EOverWrite
+	else if ((aSwitches & ~EOverWrite) != 0)
+		{
+		ret = KErrArgument;
+		}
+	else
+		{
+
+		SetFlags(aSwitches & EOverWrite, EFalse, EFalse, EFalse);
+
+		// need to signal to CFileBase that we're copying from a handle
+		// and that iSrcFile is invalid
+		iSwitches|= KCopyFromHandle;
+
+		TInt r;
+		RETURNIFERROR(r, iFs.Parse(aNew, iTrgFile),UTraceModuleEfsrv::ECFileManCopy3Return);
+
+		// Need to duplicate the RFile handle so that any threads owned
+		// by this process can use it - i.e. the worker thread
+		RETURNIFERROR(r, iSrcFileHandle.Duplicate(anOld, EOwnerProcess),UTraceModuleEfsrv::ECFileManCopy3Return);
+
+		iAction = EInternalCopyFromHandle;
+		iNumberOfFilesProcessed = 0;
+		TRAP(r,RunL());
+		ret=(r==KErrNone) ? iLastError : r;
+		DoSynchronize(r);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy3Return, MODULEUID, ret);
+	return(ret);
+	}
+
+EXPORT_C TInt CFileMan::Copy(const RFile& anOld,const TDesC& aNew,TUint aSwitches,TRequestStatus& aStatus)
+/**
+Copies from an open file handle to a destination file name.
+
+This is an asynchronous function.
+Its behaviour is the same as the synchronous overload.
+
+@param anOld     Open file handle indicating the file to be copied.
+@param aNew      Path indicating the directory (and optionally the filename)
+				 into which the file is to be copied.
+				 Any path components which are not specified here will be
+                 taken from the session path
+@param aSwitches Specify zero for no overwriting;
+                 CFileMan::EOverWrite to overwrite files with the same name;
+                 Any other flags are illegal.
+
+@param aStatus   The request status object. On request completion,
+                 indicates how the request completed:
+                 KErrNone, if successful, otherwise one of the other system-wide error
+                 codes.
+
+@return KErrNone if the asynchronous request is made successfully; KErrInUse if an asynchronous request
+					is still pending; otherwise one of the other system-wide error codes
+
+@see CFileBase::GetLastError()
+
+@capability Dependent If the path for aNew begins with /Sys then Tcb capability is required.
+@capability Dependent If the path for aNew begins with /Private and does not match
+					  this process' SID then AllFiles capability is required.
+@capability Dependent If the path for aNew begins with /Resource then Tcb capability is required.
+*/
+	{
+	TRACEMULT5(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy4, MODULEUID,
+		(TUint) this, anOld.SubSessionHandle(), aNew, aSwitches, (TUint) &aStatus);
+
+	TInt r;
+	if (iSwitches&KFManBusyFlag)
+		{
+		r = KErrInUse;
+		}
+	else
+		{
+		iStatus=&aStatus;
+		r = Copy(anOld,aNew,aSwitches);
+		}
+
+	TRACERET1(UTF::EBorder, UTraceModuleEfsrv::ECFileManCopy4Return, MODULEUID, r);
+	return(r);
+	}
+
+void CFileMan::DoCopyFromHandleL()
+//
+// Copy from open file handle
+//
+	{
+	TInt ret=0;
+	TFileName& trgName = iTmpName1;
+
+	if (iTrgFile.NamePresent())
+		{
+		trgName = iTrgFile.FullName();
+		}
+	else
+		{
+		iSrcFileHandle.Name(trgName);
+		if ((trgName.Length() + iTrgFile.DriveAndPath().Length()) > KMaxFileName)
+			{
+			iSrcFileHandle.Close();
+			User::Leave(KErrBadName);
+			}
+		trgName.Insert(0, iTrgFile.DriveAndPath());
+		}
+
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+	RFile trgFile;
+#else
+	RFile64 trgFile;
+#endif
+	TInt r=KErrNone;
+
+	if ((iSwitches&KOverWriteFlag)==0)
+		r=trgFile.Create(iFs,trgName,EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+	else
+		r=trgFile.Replace(iFs,trgName,EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
+	if (r!=KErrNone)
+		iErrorInfo = ETrgOpenFailed;
+
+	if (r == KErrNone)
+		r = DoCopy(iSrcFileHandle, trgFile, ret);
+
+	// close the (duplicated) source file handle
+	iSrcFileHandle.Close();
+
+	trgFile.Close();
+	if (ret == MFileManObserver::ECancel || (r!=KErrNone && r!=KErrAlreadyExists && iErrorInfo!=ETrgOpenFailed))
+		iFs.Delete(trgName);
+	User::LeaveIfError(r);
+	}
+
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+TInt CFileMan::DoCopy(const RFile& aSrcFile, RFile& aDstFile, TInt& aRet)
+	{
+	TInt rem;
+#else
+TInt CFileMan::DoCopy(const RFile64& aSrcFile, RFile64& aDstFile, TInt& aRet)
+	{
+	TInt64 rem;
+#endif
+	RETURNIFERRORD(r,aSrcFile.Size(rem),EFalse);
+	RETURNIFERROR(r, aDstFile.SetSize(rem),EFalse);
+
+	HBufC8* bufPtr = NULL;
+	bufPtr = AllocateBuffer(rem);
+	if (bufPtr == NULL)
+		return KErrNoMemory;
+	TPtr8 copyBuf=bufPtr->Des();
+
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+	TInt pos=0;
+#else
+	TInt64 pos=0;
+#endif
+	aRet = MFileManObserver::EContinue;
+	while(rem && aRet == MFileManObserver::EContinue)
+		{
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+		TInt s=Min(rem,copyBuf.MaxSize());
+#else
+		// Min result shall be of TInt size
+		TInt s=(TInt)(Min(rem,(TInt64)copyBuf.MaxSize()));
+#endif
+		r=aSrcFile.Read(pos,copyBuf,s);
+		if (r==KErrNone && copyBuf.Length()!=s)
+			r = KErrCorrupt;
+		if (r==KErrNone)
+			r=aDstFile.Write(pos,copyBuf,s);
+		if (r!=KErrNone)
+			break;
+		pos+= s;
+		rem-= s;
+		iBytesTransferred = s;
+		aRet = (iObserver) ? iObserver->NotifyFileManOperation() : MFileManObserver::EContinue;
+		if (aRet != MFileManObserver::EContinue && aRet != MFileManObserver::ECancel)
+			Panic(EFManBadValueFromObserver);
+		}
+
+	// need to flush the target file - otherwise if there is any dirty data this will be flushed
+	// when the file is closed and this will set the archive attribute, resulting in the file
+	// having potentially a different attribute from the source file
+	if (r == KErrNone)
+		r = aDstFile.Flush();
+
+	if (aRet != MFileManObserver::ECancel)
+		{
+		TTime lastMod;
+		if (r == KErrNone)
+			r = aSrcFile.Modified(lastMod);
+		if (r == KErrNone)
+			r = aDstFile.SetModified(lastMod);
+
+		TUint fileAttributes=0;
+		if (r == KErrNone)
+			r = aSrcFile.Att(fileAttributes);
+		if (r == KErrNone)
+			r = aDstFile.SetAtt(fileAttributes,(~fileAttributes)&KEntryAttMaskSupported);
+
+		if(r == KErrNone)
+  			r = aDstFile.Flush();
+		}
+
+	delete bufPtr;
+
+	return r;
+	}