--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_dir.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -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<TUidType> 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<TEntry> 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<KEntryArraySize> 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);
+ }
+