userlibandfileserver/fileserver/sfile/sf_nbs.cpp
changeset 0 a41df078684a
child 28 5b5d147c7838
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_nbs.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1051 @@
+// Copyright (c) 1995-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 "sf_std.h"
+
+TInt TFsMkDir::DoRequestL(CFsRequest* aRequest)
+//
+// Make a directory path.
+//
+	{
+	__PRINT(_L("TFsMkDir::DoRequestL(CFsRequest* aRequest)"));
+
+    TInt r = CheckDiskSpace(0, aRequest);
+    if(r != KErrNone)
+        return r;
+
+	r=aRequest->Drive()->CheckMount();
+	if (r!=KErrNone)
+		return(r);
+	
+    if (aRequest->Src().IsRoot())
+		return(KErrAlreadyExists);
+	
+    TPtrC ptr;
+	ptr.Set(aRequest->Src().Path().Ptr(), aRequest->Src().Path().Length()-1);
+	if (ptr.Length()<=1)
+		return(KErrBadName);
+	
+    if (IsIllegalFullName(aRequest->Src().FullName()))
+		return(KErrBadName);
+	
+    if (aRequest->Message().Int1())
+		{
+		TLex lex(ptr);
+		TFileName filename;
+		FOREVER
+			{
+			lex.Inc(); // Skip a delimiter
+			TInt res=lex.Remainder().Locate(KPathDelimiter);
+			if (res==KErrNotFound)
+				break;
+	
+    		lex.Inc(res);
+			filename+=lex.MarkedToken();	
+			lex.Mark();
+			TEntry entry;
+			if ((r=aRequest->Drive()->Entry(filename,entry))==KErrNone)
+				{
+				if (!entry.IsDir())
+					return(KErrAccessDenied);
+				continue;
+				}
+	
+    		if (r!=KErrNotFound)
+				return(r);
+	
+    		if ((r=aRequest->Drive()->MkDir(filename))!=KErrNone)
+				return(r);
+			}
+		}
+	
+    return(aRequest->Drive()->MkDir(ptr));
+	}
+
+TInt TFsMkDir::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseSubstPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysMkDir,&KCapFsPriMkDir,&KCapFsROMkDir, __PLATSEC_DIAGNOSTIC_STRING("Make Directory"));
+	return(r);
+	}
+
+
+TInt TFsRmDir::DoRequestL(CFsRequest* aRequest)
+//
+// Remove a directory.
+//
+	{
+	__PRINT(_L("TFsRmDir::DoRequestL(CFsRequest* aRequest)"));
+	if (aRequest->Src().IsRoot())
+		return(KErrInUse);
+	if (IsIllegalFullName(aRequest->Src().FullName()))
+		return(KErrBadName);
+	TPtrC ptr;
+	ptr.Set(aRequest->Src().Path().Ptr(), aRequest->Src().Path().Length()-1);
+	return(aRequest->Drive()->RmDir(ptr));
+	}
+
+TInt TFsRmDir::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseSubstPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysRmDir,&KCapFsPriRmDir,&KCapFsRORmDir, __PLATSEC_DIAGNOSTIC_STRING("Remove Directory"));
+	return(r);
+	}
+
+
+TInt TFsDelete::DoRequestL(CFsRequest* aRequest)
+//
+// Delete a file.
+//
+	{
+	__PRINT(_L("TFsDelete::DoRequestL(CFsRequest* aRequest)"));
+	return(aRequest->Drive()->Delete(aRequest->Src().FullName().Mid(2)));
+	}
+
+TInt TFsDelete::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysDelete,&KCapFsPriDelete,&KCapFsRODelete, __PLATSEC_DIAGNOSTIC_STRING("Delete"));
+	return(r);
+	}
+
+
+TInt TFsRename::DoRequestL(CFsRequest* aRequest)
+//
+// Rename a file or directory. Wild cards not allowed.
+//
+	{
+	__PRINT(_L("TFsRename::DoRequestL(CFsRequest* aRequest)"));
+    TInt r = CheckDiskSpace(0, aRequest);
+    if(r != KErrNone)
+        return r;
+	
+    r = aRequest->Drive()->Rename(aRequest->Src().FullName().Mid(2),aRequest->Dest().FullName().Mid(2));
+	return (r);
+	}
+
+TInt TFsRename::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysRename,&KCapFsPriRename,&KCapFsRORename, __PLATSEC_DIAGNOSTIC_STRING("File Server Rename"));
+	if(r!=KErrNone)
+		return(r);
+	TDrive* pOldDrive=aRequest->Drive();
+	if ((r=ParseNoWildSubstCheckPathPtr1(aRequest,aRequest->Dest()))!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Dest().FullName().Mid(2),&KCapFsSysRename,&KCapFsPriRename,&KCapFsRORename, __PLATSEC_DIAGNOSTIC_STRING("File Server Rename"));	
+	if(r == KErrNone)
+		{
+		if (pOldDrive!=aRequest->Drive())
+			r=KErrArgument;
+		}
+	return(r);
+	}
+
+
+TInt TFsReplace::DoRequestL(CFsRequest* aRequest)
+//
+// Replace an old file with a new file atomically
+//
+	{
+	__PRINT(_L("TFsReplace::DoRequestL(CFsRequest* aRequest)"));
+
+    TInt r = CheckDiskSpace(0, aRequest);
+    if(r != KErrNone)
+        return r;
+
+	return(aRequest->Drive()->Replace(aRequest->Src().FullName().Mid(2),aRequest->Dest().FullName().Mid(2)));
+	}
+
+TInt TFsReplace::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysReplace,&KCapFsPriReplace,&KCapFsROReplace, __PLATSEC_DIAGNOSTIC_STRING("File Server Replace"));	
+	if(r!=KErrNone)
+		return(r);
+	TDrive* pOldDrive=aRequest->Drive();
+	if ((r=ParseNoWildSubstCheckPtr1(aRequest,aRequest->Dest()))!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Dest().FullName().Mid(2),&KCapFsSysReplace,&KCapFsPriReplace,&KCapFsROReplace, __PLATSEC_DIAGNOSTIC_STRING("File Server Replace"));	
+	if(r == KErrNone)
+		{
+		if (pOldDrive!=aRequest->Drive())
+			r=KErrArgument;
+		}
+	return(r);
+	}
+
+
+TInt TFsEntry::DoRequestL(CFsRequest* aRequest)
+//
+// Get all the entry details.
+//
+	{
+	__PRINT(_L("TInt TFsEntry::DoRequestL(CFsRequest* aRequest)"));
+
+	TEntry t; 
+	TPtrC filePath = aRequest->Src().FullName().Mid(2);
+	TInt r=aRequest->Drive()->Entry(filePath,t);
+	if (r!=KErrNone)
+		return(r);
+
+	// If the file is open, get the file size from the CFileCB object as there may be cached data
+	CFileCB* file;
+	aRequest->Drive()->IsFileOpen(filePath, file);
+	if (file)
+		t.SetFileSize(file->CachedSize64());
+
+	TPckgC<TEntry> p(t);
+	aRequest->WriteL(KMsgPtr1,p);
+	return(KErrNone);
+	}
+
+TInt TFsEntry::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+
+	// Check the capabilites but always allow the entry to be read for private, system and 
+	// resource directories as long as there are no sub folders or files specified
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsEntry, __PLATSEC_DIAGNOSTIC_STRING("Entry"), ETrue);	
+
+	return(r);
+	}
+
+
+TInt TFsSetEntry::DoRequestL(CFsRequest* aRequest)
+//
+// Set the attributes and the modified date and time.
+//
+	{
+	__PRINT(_L("TFsSetEntry::DoRequestL(CFsRequest* aRequest)"));
+
+    TInt r = CheckDiskSpace(0, aRequest);
+    if(r != KErrNone)
+        return r;
+
+	TTime entryTime;
+	TPckgBuf<TTime> timeBuf;
+	aRequest->ReadL(KMsgPtr1,timeBuf);
+	entryTime=timeBuf();
+	const RMessage2& msg = aRequest->Message();
+
+	return(aRequest->Drive()->SetEntry(aRequest->Src().FullName().Mid(2),entryTime,msg.Int2(),msg.Int3()));
+	}
+
+
+TInt TFsSetEntry::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+ 	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysSetEntry,&KCapFsPriSetEntry,&KCapFsROSetEntry, __PLATSEC_DIAGNOSTIC_STRING("Set Entry"));	
+	return(r);
+	}
+
+LOCAL_C void FsReadFileSectionFileClose(CFsRequest* aRequest, CFileShare* aShare)
+	{
+	aRequest->Session()->DecResourceCount();
+	TInt handle = aRequest->Session()->Handles().At(aShare, EFalse);
+	aRequest->Session()->Handles().Remove(handle,ETrue);
+	// close the file share
+	aRequest->SetScratchValue64(0);
+	}
+
+LOCAL_C CFileShare* FsReadFileSectionFileOpen(CFsRequest* aRequest)
+	{
+	TInt handle;
+	TUint32 mode = EFileShareReadersOrWriters | EFileRead | EFileReadAheadOff;
+
+	TInt r = aRequest->Drive()->FileOpen(aRequest,handle,aRequest->Src().FullName().Mid(2),mode,EFileOpen);
+	if (r!=KErrNone)
+		return(NULL);
+
+	CFileShare* share = (CFileShare*) SessionObjectFromHandle(handle, FileShares->UniqueID(), aRequest->Session());
+	
+	aRequest->Session()->IncResourceCount();
+
+	CFileCB& file = share->File();
+	if (!file.FileCache())
+		{
+		FsReadFileSectionFileClose(aRequest, share);
+		share = NULL;
+		}
+	return share;
+	}
+
+TInt TFsReadFileSection::Complete(CFsRequest* aRequest)
+	{
+	FsReadFileSectionFileClose(aRequest, (CFileShare*) aRequest->ScratchValue());
+
+	return CFsRequest::EReqActionComplete;
+	}
+
+TInt TFsReadFileSection::DoRequestL(CFsRequest* aRequest)
+//
+//	Read from a file regardless of lock state
+//
+	{
+	__PRINT(_L("TFsReadFileSection::DoRequestL(CFsRequest* aRequest)"));
+	
+	TAny* pDes=(TAny*)(aRequest->Message().Ptr0());
+	TInt64 pos;
+	if(aRequest->IsDescData(KMsgPtr2))
+		{
+		TPckg<TInt64> pkPos(pos);
+		aRequest->ReadL(KMsgPtr2, pkPos);
+		}
+	else
+		{
+		pos = MAKE_TINT64(0,aRequest->Message().Int2());
+		}
+	TInt len=aRequest->Message().Int3();
+
+	// Try to open file so we can take advantage of file caching
+	CFileShare* share = FsReadFileSectionFileOpen(aRequest);
+	if (share)
+		{
+		CFsMessageRequest& msgRequest = *(CFsMessageRequest*) aRequest;
+		__ASSERT_DEBUG(msgRequest.CurrentOperationPtr() == NULL, Fault(EBadOperationIndex));
+		CFileCB& file = share->File();
+		TInt64 size = file.Size64();
+		TInt r = KErrNone;
+		if (pos > size)
+			pos = size;
+		if (pos + len > size)
+		// filesize - pos shall of TInt size
+		// Hence to suppress warning
+			len = (TInt)(size - pos);
+		if (len <= 0)
+			r = KErrArgument;
+		if (r == KErrNone)
+			r = msgRequest.PushOperation(pos, len, (TDesC8*) pDes, 0, TFsReadFileSection::Complete, 0, EFsFileRead);
+		msgRequest.SetState(CFsRequest::EReqStatePostInitialise);	// DO call PostInitialise()
+		if (r == KErrNone)
+			{
+			aRequest->SetScratchValue64( MAKE_TINT64(ETrue, (TUint) share) );
+			return CFsRequest::EReqActionBusy; // dispatch the request again
+			}
+		FsReadFileSectionFileClose(aRequest, share);
+		}
+
+	TInt r = KErrNone;
+	if (len < 0)
+		r = KErrArgument;
+	else if (len > 0)
+		r = aRequest->Drive()->ReadFileSection64(aRequest->Src().FullName().Mid(2),pos,pDes,len,aRequest->Message());
+
+	// zero return buffer, but only if we haven't written any data to it already, otherwise kernel's
+	// writeback of descriptor length will conflict with that wrttien by media driver
+	if (r != KErrNone || len == 0)
+		aRequest->WriteL(KMsgPtr0,KNullDesC8);
+	
+	return r == KErrEof ? KErrNone : r;  
+	}
+
+
+TInt TFsReadFileSection::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstFileCheckPtr1(aRequest,aRequest->Src());
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysReadFileSection,&KCapFsPriReadFileSection, __PLATSEC_DIAGNOSTIC_STRING("Read File Section"));	
+	return(r);
+	}
+
+
+
+TInt TFsCheckDisk::DoRequestL(CFsRequest* aRequest)
+//
+// Check the disk's integrity
+//
+	{
+
+	__PRINT(_L("TFsCheckDisk::DoRequestL(CFsRequest* aRequest)"));
+
+	// flush all files on this drive
+	TInt r = aRequest->Drive()->FlushCachedFileInfo();
+	if (r == CFsRequest::EReqActionBusy)	// ignore any flush errors
+		return(r);
+
+	return(aRequest->Drive()->CheckDisk());
+	}
+
+
+TInt TFsCheckDisk::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	if (!KCapFsCheckDisk.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("CheckDisk")))						
+		return KErrPermissionDenied;
+	return ParseSubstPtr0(aRequest,aRequest->Src());	//may make the rfs function call take a drive instead of path
+	}
+
+TInt TFsScanDrive::DoRequestL(CFsRequest* aRequest)
+//
+//
+//
+	{
+	__PRINT(_L("TFsScanDrive::DoRequestL(CFsRequest* aRequest)"));
+
+	// flush all files on this drive
+	TInt r = aRequest->Drive()->FlushCachedFileInfo();
+	if (r == CFsRequest::EReqActionBusy)	// ignore any flush errors
+		return(r);
+
+	r=aRequest->Drive()->CheckMount();
+	if(r!=KErrNone)
+		return(r);
+	if (aRequest->Drive()->CurrentMount().LockStatus()<0)
+		return(KErrInUse);
+	r=aRequest->Drive()->ScanDrive();
+	// notify sessions since drive contents may have changed
+	if(r==KErrNone)
+		FsNotify::DiskChange(aRequest->DriveNumber());
+	return(r);
+	}
+
+TInt TFsScanDrive::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r;
+	if(!KCapFsScanDrive.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("ScanDrive")))	
+		return KErrPermissionDenied;
+	r=ParseSubstPtr0(aRequest,aRequest->Src());		//may make the rfs function call take a drive instead of path
+	return(r);										//then  no need for parse, just needs to check for susted and reject them
+	}
+
+TInt TFsGetShortName::DoRequestL(CFsRequest* aRequest)
+//
+// Get the short name associated with a long file name
+//
+	{
+	__PRINT(_L("TFsGetShortName::DoRequestL(CFsRequest* aRequest)"));
+	TBuf<0x10> shortName;
+	TInt r=aRequest->Drive()->GetShortName(aRequest->Src().FullName().Mid(2),shortName);
+	if (r!=KErrNone)
+		return(r);
+	aRequest->WriteL(KMsgPtr1,shortName);
+	return(KErrNone);
+	}
+
+TInt TFsGetShortName::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());	
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysGetShortName,&KCapFsPriGetShortName, __PLATSEC_DIAGNOSTIC_STRING("Get Short Name"));	
+	return(r);
+	}
+
+
+TInt TFsGetLongName::DoRequestL(CFsRequest* aRequest)
+//
+// Get the long name associated with a short file name
+//
+	{
+	__PRINT(_L("TFsGetLongName::DoRequestL(CFsRequest* aRequest)"));
+	TFileName longName;
+	TInt r=aRequest->Drive()->GetLongName(aRequest->Src().FullName().Mid(2),longName);
+	if (r!=KErrNone)
+		return(r);
+	aRequest->WriteL(KMsgPtr1,longName);
+	return(KErrNone);
+	}
+
+TInt TFsGetLongName::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());	
+	if (r!=KErrNone)
+		return(r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysGetLongName,&KCapFsPriGetLongName, __PLATSEC_DIAGNOSTIC_STRING("Get Long Name"));	
+	return(r);
+	}
+
+
+TInt TFsIsFileInRom::DoRequestL(CFsRequest* aRequest)
+//
+// Return the address of the file
+//
+	{
+
+	__PRINT(_L("DoIsFileInRom"));
+	TUint8* fileStart;
+	TInt r=aRequest->Drive()->IsFileInRom(aRequest->Src().FullName().Mid(2),fileStart);
+	if (r!=KErrNone)
+		return(r);
+	TPckgBuf<TUint8*> buf(fileStart);
+	aRequest->WriteL(KMsgPtr1,buf);
+	return(KErrNone);
+	}
+
+TInt TFsIsFileInRom::Initialise(CFsRequest* aRequest)
+//
+//	
+//
+	{	
+	TInt r=ParseNoWildSubstCheckPathPtr0(aRequest,aRequest->Src());	
+	if (r!=KErrNone)
+		return (r);
+	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysIsFileInRom,&KCapFsPriIsFileInRom, __PLATSEC_DIAGNOSTIC_STRING("Is File In Rom"));	
+	return(r);
+	}
+
+
+TInt TFsIsValidName::Initialise(CFsRequest* /*aRequest*/)
+//
+//	
+//
+	{
+	return(KErrNone);
+	}
+
+
+TInt TFsIsValidName::DoRequestL(CFsRequest* aRequest)
+//
+//	Determine whether the name is valid
+//	If returnInvalidChar flag is set - determine the invalid character and
+//	return it to the client
+//  If TNameValidParam is specified determine the position of the invalid character
+//  and return it to the client.
+	{
+	__PRINT(_L("DoFsIsValidName"));
+
+	TParse parse; 
+	const TAny* pParam = aRequest->Message().Ptr3();
+	if(pParam == NULL)
+		{
+		//	We need to call DoFsIsValidName	to determine what the invalid character is
+		TInt r=ParseSubstPtr0(aRequest,parse);
+		if ((r!=KErrNone) && (r!=KErrBadName))
+			return(r);
+		TBool retInvChar;
+		TPckg<TBool> bPckg(retInvChar);
+		aRequest->ReadL(KMsgPtr1,bPckg);
+		if (!retInvChar)
+			//	Determine whether the name is invalid but don't bother finding out which
+			//	character (if any) is illegal
+			{  
+			TInt r=ParseNoWildSubstCheckPtr0(aRequest,parse);	
+			if ((r!=KErrNone) || IsIllegalFullName(parse.FullName().Mid(2)))
+				return(KErrBadName);
+			return(KErrNone);
+			}
+		else	
+			{
+			//	Determine whether the name is invalid and return any offending character 	
+			TText badChar=' ';
+			TPckg<TText> pText(badChar);
+				
+			TInt r=ParseSubstPtr0(aRequest,parse);
+			if (r==KErrBadName)	//	Name is > 256 characters or an illegal character 
+				{				//	was encountered before path was completely parsed
+				TFileName name;
+				aRequest->ReadL(KMsgPtr0,name);
+				TNameChecker checkName(name);
+				checkName.IsIllegalChar(badChar);								
+				aRequest->WriteL(KMsgPtr2,pText);
+				return(KErrBadName);
+				}
+			//	Weed out invalid * or ? in the filename (or no name and extension at all)
+			r=ParseNoWildSubstCheckPtr0(aRequest,parse);	
+			if (r==KErrBadName)
+				{
+				if (parse.IsKMatchAny())
+					badChar=KMatchAny;		//	Offending character is '*'
+				else if (parse.IsKMatchOne())
+					badChar=KMatchOne;		//	Offending character is '?'
+				aRequest->WriteL(KMsgPtr2,pText);
+				return(KErrBadName);
+				}
+
+			//	Weed out any other outstanding illegal characters in filename or path	
+			TNameChecker checkName(parse.FullName().Mid(2));
+			if (checkName.IsIllegalName(badChar))
+				{
+				aRequest->WriteL(KMsgPtr2,pText);
+				return(KErrBadName);
+				}
+			else					//	No invalid characters in name
+				{					//	Set badChar to '\0'		
+				badChar='\0';		
+				aRequest->WriteL(KMsgPtr2,pText);
+				return(KErrNone);	
+				}
+			}
+		}
+	else //new API implementation
+		{
+		RFs::TNameValidParam param;
+		TPckg<RFs::TNameValidParam> paramPckg(param);
+		aRequest->ReadL(KMsgPtr3,paramPckg);
+		TUint nameLen=(TUint)aRequest->GetDesLength(KMsgPtr0);
+		if(nameLen == 0)// a name must be specified
+			{
+			param.iError = RFs::TNameValidParam::ErrBadName;
+			param.iInvalidCharPos = 0;
+			aRequest->WriteL(KMsgPtr3,paramPckg);
+			return KErrBadName;
+			}
+		if(param.iUseSessionPath)
+			nameLen += aRequest->Session()->Path().Length();
+		if(nameLen > (TUint)KMaxFileName)
+			{
+			param.iError = RFs::TNameValidParam::ErrNameTooLong;
+			param.iInvalidCharPos = 0;
+			aRequest->WriteL(KMsgPtr3,paramPckg);
+		   	return KErrBadName;
+			}
+		TFileName fileName;
+		TInt driveLength = 2;
+		TText badChar;
+		TRAPD(r, aRequest->ReadL(KMsgPtr0,fileName));
+		if(KErrNone == r)
+			{
+			r=ParseSubstPtr0(aRequest,parse,param.iUseSessionPath);
+			if (KErrBadName  == r) 	//	An illegal character 
+				{					//	was encountered before path was completely parsed
+				TNameChecker checkName(fileName);
+				if(checkName.IsIllegalChar(badChar))
+					{
+					param.iError = RFs::TNameValidParam::ErrBadCharacter;
+					param.iInvalidCharPos = fileName.LocateReverse(badChar)+1;
+					aRequest->WriteL(KMsgPtr3,paramPckg);
+					return KErrBadName;
+					}
+				param.iError = RFs::TNameValidParam::ErrBadName;
+				param.iInvalidCharPos = 0;
+				aRequest->WriteL(KMsgPtr3,paramPckg);
+				return KErrBadName;
+				}
+			//	Weed out invalid * or ? in the filename
+			r=ParseNoWildSubstPtr0(aRequest,parse,param.iUseSessionPath);
+			if(KErrBadName == r)
+				{
+				if(parse.IsWild())	
+					{
+					if (parse.IsKMatchAny())
+						{// offending character is '*'
+						param.iError = RFs::TNameValidParam::ErrBadCharacter;
+						param.iInvalidCharPos = fileName.LocateReverse(KMatchAny)+1;
+						aRequest->WriteL(KMsgPtr3,paramPckg);
+						return KErrBadName;
+						}
+					else if (parse.IsKMatchOne())
+						{//offending character is '?'
+						param.iError = RFs::TNameValidParam::ErrBadCharacter;
+						param.iInvalidCharPos = fileName.LocateReverse(KMatchOne)+1;
+						aRequest->WriteL(KMsgPtr3,paramPckg);
+			    		return KErrBadName;
+						}
+					}
+				param.iError = RFs::TNameValidParam::ErrBadName;
+				param.iInvalidCharPos = 0;
+				aRequest->WriteL(KMsgPtr3,paramPckg);
+				return KErrBadName;
+				}
+			if(!param.iUseSessionPath && !parse.DrivePresent())
+				driveLength = 0;
+			//	Weed out any other outstanding illegal characters in filename or path
+			TNameChecker checkName(parse.FullName().Mid(driveLength));
+			badChar = ' ';	
+			if (checkName.IsIllegalName(badChar))
+				{
+				if(badChar == ' ')
+					{
+					param.iError = RFs::TNameValidParam::ErrBadName;
+					param.iInvalidCharPos = 0;
+					aRequest->WriteL(KMsgPtr3,paramPckg);
+					return KErrBadName;
+					}
+				else
+					{
+					if(badChar == '.')
+						{
+						param.iError = RFs::TNameValidParam::ErrBadCharacter;
+						param.iInvalidCharPos = fileName.Locate(badChar)+1;
+						}
+					else
+						{
+						param.iError = RFs::TNameValidParam::ErrBadCharacter;
+						param.iInvalidCharPos = fileName.LocateReverse(badChar)+1;
+						}
+					aRequest->WriteL(KMsgPtr3,paramPckg);
+					return KErrBadName;
+					}
+				}
+			else					//	No invalid characters in name
+				{
+				param.iError = RFs::TNameValidParam::ErrNone;
+				param.iInvalidCharPos = 0;
+				aRequest->WriteL(KMsgPtr3,paramPckg);
+				return KErrNone;		
+				}
+			}
+		else
+			return r;//read is not successful.
+		}
+	}
+				
+	
+TInt TFsLockDrive::DoRequestL(CFsRequest* aRequest)
+//
+// Lock media device
+//
+	{
+	__PRINT(_L("TFsLockDrive::DoRequestL(CFsRequest* aRequest)"));	
+	TMediaPassword oldPw;
+	TMediaPassword newPw;
+	aRequest->ReadL(KMsgPtr1,oldPw);
+	aRequest->ReadL(KMsgPtr2,newPw);
+	return(aRequest->Drive()->LockDevice(oldPw,newPw,aRequest->Message().Int3()));
+	}
+
+
+TInt TFsLockDrive::Initialise(CFsRequest* aRequest)
+//
+// 
+//
+	{
+	if (!KCapFsLockDrive.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Lock Drive")))
+		return KErrPermissionDenied;
+	TInt r=ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
+	return(r);
+	}
+
+TInt TFsUnlockDrive::DoRequestL(CFsRequest* aRequest)
+//
+// Unlock media device
+//
+	{
+	__PRINT(_L("TFsUnlockDrive::DoRequestL(CFsRequest* aRequest)"));
+	TMediaPassword pW;
+	aRequest->ReadL(KMsgPtr1,pW);
+	return(aRequest->Drive()->UnlockDevice(pW,aRequest->Message().Int2()));
+	}
+
+
+TInt TFsUnlockDrive::Initialise(CFsRequest* aRequest)
+//
+// 
+//
+	{
+	if (!KCapFsUnlockDrive.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Unlock Drive")))
+		return KErrPermissionDenied;
+	TInt r=ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
+	return(r);
+	}
+
+TInt TFsClearPassword::DoRequestL(CFsRequest* aRequest)
+//
+// Clears password of media device
+//
+	{
+	__PRINT(_L("TFsClearPassowrd::DoRequestL(CFsRequest* aRequest)"));	
+	TMediaPassword pW;
+	aRequest->ReadL(KMsgPtr1,pW);
+	return(aRequest->Drive()->ClearDevicePassword(pW));
+	}
+
+
+TInt TFsClearPassword::Initialise(CFsRequest* aRequest)
+//
+//
+//
+	{
+	if (!KCapFsClearPassword.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Clear Password")))
+		return KErrPermissionDenied;
+	return ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
+	}
+
+TInt TFsErasePassword::DoRequestL(CFsRequest* aRequest)
+//
+// Erase the password from the media device
+//
+	{
+	__PRINT(_L("TFsErasePassword::DoRequestL(CFsRequest* aRequest)"));
+	return(aRequest->Drive()->EraseDevicePassword());
+	}
+
+
+TInt TFsErasePassword::Initialise(CFsRequest* aRequest)
+//
+// 
+//
+	{
+	if (!KCapFsErasePassword.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Erase Password")))
+		return KErrPermissionDenied;
+	return ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
+
+	}
+
+
+TInt TFsSessionToPrivate::DoRequestL(CFsRequest* aRequest)
+//
+//	Set session path to the private directory (does not need to exist)
+//
+	{
+	TBuf<30> pPath;	
+	pPath=_L("?:\\Private\\");	
+	pPath[0]= (TText)('A'+ aRequest->Message().Int0());
+	pPath.AppendNumFixedWidth(aRequest->Message().SecureId().iId, EHex, 8);
+	pPath += KSlash;
+	HBufC* pP = pPath.Alloc();
+	if (pP==NULL)
+		return KErrNoMemory;
+	delete &aRequest->Session()->Path();
+	aRequest->Session()->SetPath(pP);
+	return KErrNone;
+	}
+
+	
+TInt TFsSessionToPrivate::Initialise(CFsRequest* /*aRequest*/) 
+//
+//	standard initialisation
+//
+	{
+	return KErrNone;
+	}
+
+TInt TFsPrivatePath::DoRequestL(CFsRequest* aRequest)
+//
+//	may be able to do this user side !!!
+//
+	{
+	TSecureId appUID = aRequest->Message().SecureId();	
+	TFileName pPath(KPrivateSlash);	
+	pPath.AppendNumFixedWidth(appUID.iId, EHex, 8);
+	pPath += KSlash;
+	aRequest->WriteL(KMsgPtr0,pPath);
+
+	return KErrNone;	
+
+	}
+
+TInt TFsPrivatePath::Initialise(CFsRequest* /*aRequest*/) 
+//
+//
+//
+	{
+	return KErrNone;
+	}
+
+
+TInt TFsCreatePrivatePath::DoRequestL(CFsRequest* aRequest)
+//
+//	create the private path unless it already exists
+//
+	{
+    TInt ret = CheckDiskSpace(0, aRequest);
+    if(ret != KErrNone)
+        return ret;
+
+	TBuf<30> pPath(KPrivate);	
+	pPath += KSlash;
+	pPath.AppendNumFixedWidth(aRequest->Message().SecureId().iId, EHex, 8);
+	TEntry e;
+	ret=aRequest->Drive()->CheckMount();
+	if (ret!=KErrNone)
+		return ret;
+
+	//no point going mad on sanity check we know it's not root or a bad name
+	ret =aRequest->Drive()->Entry(KPrivate(),e);
+	if(ret != KErrNone)
+		{
+		if(ret==KErrNotFound)
+			{
+			ret = aRequest->Drive()->MkDir(KPrivate());	
+			if(ret != KErrNone)
+				return ret;
+			}
+		else
+			return ret;
+		}
+	ret =aRequest->Drive()->Entry(pPath,e);
+	if(ret==KErrPathNotFound || ret==KErrNotFound || !e.IsDir())	
+		{	
+		if((ret=aRequest->Drive()->MkDir(pPath ))!=KErrNone)
+			return ret;			
+		}
+	return ret;
+	}
+
+
+TInt TFsCreatePrivatePath::Initialise(CFsRequest* aRequest) 
+//
+//
+//
+	{
+	TInt r=ValidateDriveDoSubst(aRequest->Message().Int0(),aRequest);
+	return(r);
+	}
+
+TInt TFsFinaliseDrive::DoRequestL(CFsRequest* aRequest)
+	{
+	__PRINT(_L("TFsFinaliseDrive::DoRequestL"));
+
+	TInt r=aRequest->Drive()->CheckMount();
+	if (r!=KErrNone)
+		return r;
+
+    const TInt nMode = aRequest->Message().Int1(); //-- finalisation mode, see RFs::TFinaliseDrvMode
+
+	return aRequest->Drive()->FinaliseMount(nMode);
+	}
+
+/**
+    Finalise the drive
+*/
+TInt TFsFinaliseDrive::Initialise(CFsRequest* aRequest)
+	{
+	if (!KCapFsFinaliseDrive.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Finalise Drive")))
+		return KErrPermissionDenied;
+
+	const TInt nDrv  = aRequest->Message().Int0(); //-- the drive number to be finalised
+
+    TInt r = ValidateDriveDoSubst(nDrv, aRequest);
+    if (r != KErrNone)
+        return r;
+
+	TDrive& d = TheDrives[nDrv];
+    if(!d.GetFSys())
+	    return KErrNotFound; //-- something wrong with this drive 
+
+    
+    //-- check the drive attributes
+    const TUint KDrvAttExclude = KDriveAttRom | KDriveAttRedirected; //-- the drive attributes to exlcude from the finalisation
+    if(d.Att() & KDrvAttExclude) 
+        return KErrNotSupported; //-- finalisation isn't supported for these drives
+
+	return KErrNone;
+	}
+
+/**  Set System Drive (used by GetSystemDrive and SystemDriveChar) */
+TInt TFsSetSystemDrive::DoRequestL(CFsRequest* aRequest)
+	{
+    __PRINT(_L("TFsSetSystemDrive::DoRequestL()"));
+    TInt drive;
+	TInt err = RProperty::Get(TSecureId(KFileServerUidValue), KSystemDriveKey, drive);
+	if(err == KErrNone)
+		{
+		__PRINT1(_L("TFsSetSystemDrive::DoRequestL() drv:%d is already defined as system!"), drive);
+        return KErrAlreadyExists;
+		}
+	
+    drive = aRequest->Message().Int0();    
+	__ASSERT_ALWAYS(drive>=EDriveA && drive<=EDriveZ, Fault(EInvalidDrive));
+
+	//Calculates the total number of valid drives present and set RAM as a
+	//system drive only if one valid drive is present.
+	TInt total_drive = 0;
+	for (TInt driveNumber=0; driveNumber<KMaxDrives; driveNumber++)
+		{
+		if(TheDrives[driveNumber].GetFSys() != NULL)  // is a valid drive
+			total_drive++;
+		}
+	aRequest->SetDrive(&TheDrives[drive]);
+	FsThreadManager::LockDrive(aRequest->DriveNumber());
+	TDriveInfo info;
+	aRequest->Drive()->DriveInfo(info);
+	FsThreadManager::UnlockDrive(aRequest->DriveNumber());
+
+	__PRINT1(_L("TFsSetSystemDrive::DoRequestL() total drives:%d"), total_drive);
+    __PRINT3(_L("TFsSetSystemDrive::DoRequestL() setting sys:%d, Media:0x%x, DrvAtt:0x%x"), drive, info.iType, info.iDriveAtt);
+
+    //-- 1. check media type of the system drive.
+    __ASSERT_ALWAYS(info.iType==EMediaHardDisk || info.iType==EMediaFlash || info.iType==EMediaNANDFlash || info.iType==EMediaRam, Fault(EInvalidDrive));
+    
+    if(info.iType == EMediaRam)
+		{//-- It is not nice to use RAM drive as a system one because it might non be persistent, but acceptable though. 
+         __PRINT(_L("TFsSetSystemDrive::DoRequestL() WARNING: RAM drive is set as system drive!"));
+        }
+   
+    //-- 2. check drive attributes for the system drive
+    const TUint requiredDrvAtt   = KDriveAttLocal|KDriveAttInternal;
+    const TUint prohibitedDrvAtt = KDriveAttRom|KDriveAttRedirected|KDriveAttSubsted|KDriveAttRemovable;
+
+    ASSERT(!(prohibitedDrvAtt & requiredDrvAtt));
+    if( !(info.iDriveAtt & requiredDrvAtt) || (info.iDriveAtt & prohibitedDrvAtt))
+        {
+        __PRINT2(_L("TFsSetSystemDrive::DoRequestL(), Wrong Drive attributes! req:0x%x, disallowed:0x%x"), requiredDrvAtt, prohibitedDrvAtt);
+        Fault(EInvalidDrive);
+        }
+
+
+	RProcess p;
+	TSecurityPolicy policy(p.SecureId());
+	err = RProperty::Define(TSecureId(KFileServerUidValue), KSystemDriveKey, RProperty::EInt, TSecurityPolicy::EAlwaysPass, policy);
+	if(err == KErrNone)
+		{
+		err = RProperty::Set(TSecureId(KFileServerUidValue), KSystemDriveKey, drive);
+		}
+	__ASSERT_ALWAYS(err==KErrNone, User::Invariant());
+    
+    return err;
+	}
+	
+/** Checks if setting System Drive is allowed */
+TInt TFsSetSystemDrive::Initialise(CFsRequest* aRequest)
+	{
+	if (!KCapFsSetSystemDrive.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Set System Drive")))
+		{
+		return KErrPermissionDenied;
+		}
+    return KErrNone;
+	}