diff -r 000000000000 -r 96e5fb8b040d userlibandfileserver/fileserver/sfile/sf_dir.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfile/sf_dir.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,303 @@ +// 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: +// f32\sfile\sf_dir.cpp +// +// + +#include "sf_std.h" + +LOCAL_C CDirCB* GetDirFromHandle(TInt aHandle,CSessionFs* aSession) +// +// Get the dir control block from its handle. +// + { + return((CDirCB*)(SessionObjectFromHandle(aHandle,Dirs->UniqueID(),aSession))); + } + +LOCAL_C TInt DoInitialise(CFsRequest* aRequest) +// +// Determine asynchronicity from dir control block +// + { + CDirCB* dir; + dir=GetDirFromHandle(aRequest->Message().Int3(),aRequest->Session()); + if(!dir) + return(KErrBadHandle); + aRequest->SetDrive(&dir->Drive()); + aRequest->SetScratchValue((TUint)dir); + return KErrNone; + } + +#ifndef __ARMCC__ +LOCAL_C +#endif +void fsDirReadPacked(TEntry* pE,TEntry* pEnd,volatile TInt& aLen,CDirCB& aDir) +// +// Read packed directory entries. +// + { + + FOREVER + { + TEntry e; + + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &aDir); + aDir.ReadL(e); + TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, + KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize); + TInt len=EntrySize(e, EFalse); + TInt rLen=EntrySize(e, ETrue); + TEntry* pX=PtrAdd(pE,rLen); + if (pX>pEnd) + { + + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameL, EF32TraceUidFileSys, &aDir); + aDir.StoreLongEntryNameL(e.iName); + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameLRet, EF32TraceUidFileSys, KErrNone); + + aDir.SetPending(ETrue); + break; + } + aLen+=rLen; + Mem::Copy(pE,&e,len); + + /** + * Flag the entry with KEntryAttPacked so we can unpack + * these fields as required at a later date... + */ + pE->iAtt |= KEntryAttPacked; + + /** + * ...and pack the iSizeHigh and iReserved fields to the end of the name string + */ + TUint32* pSizeHighSrc = PtrAdd((TUint32*)&e, sizeof(TEntry) - 2*sizeof(TInt)); + TUint32* pSizeHighDst = PtrAdd((TUint32*)pE, EntrySize(*pE, EFalse)); + + *pSizeHighDst++ = *pSizeHighSrc++; // Copy length + *pSizeHighDst = *pSizeHighSrc; // Copy reserved + + pE=pX; + } + } + +TInt TFsDirOpen::DoRequestL(CFsRequest* aRequest) +// +// Open a directory. +// + { + + __PRINT(_L("TFsDirOpen::DoRequestL(CFsRequest* aRequest)")); + TInt h; + TUidType uidType; + TPckgBuf pckgUid; + aRequest->ReadL(KMsgPtr2,pckgUid); + uidType=pckgUid(); + TInt r=aRequest->Drive()->DirOpen(aRequest->Session(),h,aRequest->Src().FullName().Mid(2),aRequest->Message().Int1(),uidType); + if (r!=KErrNone) + return(r); + + + //DirRead does not have a filename / src stored, so if there are plugins installed which + //wish to intercept dirread1/packed then store the name in CDirCB::iName now. + CFsPlugin* plugin = NULL; + //Get the next plugin which is mounted on this drive (IsMounted called in NextPlugin) + //Do not check whether we're registered for current operation (in case not registered for EFsDirOpen) + while(FsPluginManager::NextPlugin(plugin,(CFsMessageRequest*)aRequest,(TBool)ETrue,(TBool)EFalse)==KErrNone && plugin) + { + if(plugin->IsRegistered(EFsDirReadOne) || + plugin->IsRegistered(EFsDirReadPacked) || + plugin->IsRegistered(EFsDirSubClose)) + { + CDirCB* dir = GetDirFromHandle(h,aRequest->Session()); + TPtrC name = aRequest->Src().FullName(); + r = dir->SetName(&name); + CheckForLeaveAfterOpenL(r, aRequest, h); + break; + } + } + + TPtrC8 pH((TUint8*)&h,sizeof(TInt)); + TRAP(r,aRequest->WriteL(KMsgPtr3,pH)) + CheckForLeaveAfterOpenL(r, aRequest, h); + aRequest->Session()->IncResourceCount(); + return(KErrNone); + } + + +TInt TFsDirOpen::Initialise(CFsRequest* aRequest) +// +// +// + { + + TInt r=ParseSubstPtr0(aRequest,aRequest->Src()); + if (r!=KErrNone) + return(r); + r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysDirOpen,&KCapFsPriDirOpen, __PLATSEC_DIAGNOSTIC_STRING("Dir Open")); + if(r != KErrNone) + return r; + return KErrNone; + } + + +TInt TFsDirReadOne::DoRequestL(CFsRequest* aRequest) +// +// Read one directory entry. +// + { + __PRINT(_L("TFsDirReadOne::DoRequestL(CFsRequest* aRequest)")); + CDirCB* dir=(CDirCB*)aRequest->ScratchValue(); + TInt r=dir->CheckMount(); + if (r!=KErrNone) + return(r); + TEntry e; + + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &dir); + TRAP(r,dir->ReadL(e)) + TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, + KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize); + + + if (r==KErrNone) + { + TPckgC pE(e); + aRequest->WriteL(KMsgPtr0,pE); + } + return(r); + } + +TInt TFsDirReadOne::Initialise(CFsRequest* aRequest) +// +// +// + { + return(DoInitialise(aRequest)); + } + +TInt TFsDirReadPacked::DoRequestL(CFsRequest* aRequest) +// +// Read packed directory entries. +// + { + + __PRINT(_L("TFsDirReadPacked::DoRequestL(CFsRequest* aRequest)")); + CDirCB* dir=(CDirCB*)aRequest->ScratchValue(); + TInt r=dir->CheckMount(); + if (r!=KErrNone) + return(r); + + TBuf8 buf; + TEntry* pE=(TEntry*)buf.Ptr(); + TEntry* pEnd=PtrAdd(pE,KEntryArraySize); + volatile TInt len=0; + TRAP(r,fsDirReadPacked(pE,pEnd,len,*(dir))); + buf.SetLength(len); + aRequest->WriteL(KMsgPtr0,buf); + return(r); + } + +TInt TFsDirReadPacked::Initialise(CFsRequest* aRequest) +// +// Call GetDirFromHandle to determine asynchronicity *** +// + { + return(DoInitialise(aRequest)); + } + + + + +/** +Default cosntructor. +*/ +EXPORT_C CDirCB::CDirCB() + { + +// iPending=EFalse; +// iDrive=NULL; +// iMount=NULL; + } + + + + +/** +Destructor. + +Frees resources before destruction of the object. +*/ +EXPORT_C CDirCB::~CDirCB() + { + if(iMount) + { + RemoveResource(*iMount); + iMount->Close(); + } + } + +TInt CDirCB::CheckMount() +// +// Check that the media is still mounted. +// + { + + TDrive& d=Drive(); + TInt r=d.CheckMount(); + if (r!=KErrNone) + return(r); + if (&Mount()!=&d.CurrentMount()) + return(KErrDisMounted); + return(KErrNone); + } + +EXPORT_C void CDirCB::InitL(TDrive* aDrive) +// +// Initialise +// + { + DoInitL(aDrive->DriveNumber()); + iDrive=aDrive; + iMount=&aDrive->CurrentMount(); + User::LeaveIfError(iMount->Open()); + } + + + + +/** +Stores a long full entry name, a TEntry::iName value, into a buffer, +re-allocating the buffer first, if necessary, to make it large enough. + +The function should be implemented by a derived class; this implementation +is empty. + +This function is called by a file server reading successive entries, +when the file server reads an entry for which the full file name is longer than +the maximum buffer size. Once this function has been called, the iPending flag +is set to true by the file server and, on the next call to ReadL(), +the buffer created in this function is used to store the long entry name. + +The function should leave with an appropriate error code on error detection. + +@param aName The name to be set to a newly read entry. +*/ +EXPORT_C void CDirCB::StoreLongEntryNameL(const TDesC& /*aName*/) + {} + + +EXPORT_C TInt CDirCB::GetInterface(TInt /*aInterfaceId*/,TAny*& /*aInterface*/,TAny* /*aInput*/) + { + return(KErrNotSupported); + } +