userlibandfileserver/fileserver/sfile/sf_dir.cpp
changeset 0 a41df078684a
child 134 95847726fe57
child 256 c1f20ce4abcf
--- /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);
+	}
+