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