--- /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;
+ }