os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_dir.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32\sfile\sf_dir.cpp
    15 // 
    16 //
    17 
    18 #include "sf_std.h"
    19 
    20 LOCAL_C CDirCB* GetDirFromHandle(TInt aHandle,CSessionFs* aSession)
    21 //
    22 // Get the dir control block from its handle.
    23 //
    24 	{
    25 	return((CDirCB*)(SessionObjectFromHandle(aHandle,Dirs->UniqueID(),aSession)));
    26 	}
    27 
    28 LOCAL_C TInt DoInitialise(CFsRequest* aRequest)
    29 //
    30 //	Determine asynchronicity from dir control block
    31 //
    32 	{
    33 	CDirCB* dir;
    34 	dir=GetDirFromHandle(aRequest->Message().Int3(),aRequest->Session());
    35 	if(!dir)
    36 		return(KErrBadHandle);
    37 	aRequest->SetDrive(&dir->Drive());
    38 	aRequest->SetScratchValue((TUint)dir);
    39 	return KErrNone;
    40 	}
    41 
    42 #ifndef __ARMCC__
    43 LOCAL_C 
    44 #endif
    45 void fsDirReadPacked(TEntry* pE,TEntry* pEnd,volatile TInt& aLen,CDirCB& aDir)
    46 //
    47 // Read packed directory entries.
    48 //
    49 	{
    50 
    51 	FOREVER
    52 		{
    53 		TEntry e;
    54 
    55 		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &aDir);
    56 		aDir.ReadL(e);
    57 		TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, 
    58 			KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize);
    59 		TInt len=EntrySize(e, EFalse);
    60 		TInt rLen=EntrySize(e, ETrue);
    61 		TEntry* pX=PtrAdd(pE,rLen);
    62 		if (pX>pEnd)
    63 			{
    64 
    65 			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameL, EF32TraceUidFileSys, &aDir);
    66 			aDir.StoreLongEntryNameL(e.iName);
    67 			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameLRet, EF32TraceUidFileSys, KErrNone);
    68 
    69 			aDir.SetPending(ETrue);
    70 			break;
    71 			}
    72 		aLen+=rLen;
    73 		Mem::Copy(pE,&e,len);
    74 
    75 		/**
    76 		 * Flag the entry with KEntryAttPacked so we can unpack
    77 		 * these fields as required at a later date...
    78 		 */
    79 		pE->iAtt |= KEntryAttPacked;
    80 
    81 		/**
    82 		 * ...and pack the iSizeHigh and iReserved fields to the end of the name string
    83 		 */
    84 		TUint32* pSizeHighSrc = PtrAdd((TUint32*)&e, sizeof(TEntry) - 2*sizeof(TInt));
    85 		TUint32* pSizeHighDst = PtrAdd((TUint32*)pE, EntrySize(*pE, EFalse));
    86 
    87 		*pSizeHighDst++ = *pSizeHighSrc++;	// Copy length
    88 		*pSizeHighDst   = *pSizeHighSrc;	// Copy reserved
    89 
    90 		pE=pX;
    91 		}
    92 	}
    93 
    94 TInt TFsDirOpen::DoRequestL(CFsRequest* aRequest)
    95 //
    96 // Open a directory.
    97 //
    98 	{
    99 
   100 	__PRINT(_L("TFsDirOpen::DoRequestL(CFsRequest* aRequest)"));
   101 	TInt h;
   102 	TUidType uidType;
   103 	TPckgBuf<TUidType> pckgUid;
   104 	aRequest->ReadL(KMsgPtr2,pckgUid);
   105 	uidType=pckgUid();
   106 	TInt r=aRequest->Drive()->DirOpen(aRequest->Session(),h,aRequest->Src().FullName().Mid(2),aRequest->Message().Int1(),uidType);
   107 	if (r!=KErrNone)
   108 		return(r);
   109 
   110 	
   111 	//DirRead does not have a filename / src stored, so if there are plugins installed which
   112 	//wish to intercept dirread1/packed then store the name in CDirCB::iName now.
   113 	CFsPlugin* plugin = NULL;
   114 	//Get the next plugin which is mounted on this drive (IsMounted called in NextPlugin)
   115 	//Do not check whether we're registered for current operation (in case not registered for EFsDirOpen)
   116 	while(FsPluginManager::NextPlugin(plugin,(CFsMessageRequest*)aRequest,(TBool)ETrue,(TBool)EFalse)==KErrNone && plugin)
   117 		{
   118 		if(plugin->IsRegistered(EFsDirReadOne) ||
   119 			plugin->IsRegistered(EFsDirReadPacked) ||
   120 			plugin->IsRegistered(EFsDirSubClose))
   121 			{
   122 			CDirCB* dir = GetDirFromHandle(h,aRequest->Session());
   123 			TPtrC name = aRequest->Src().FullName();
   124 			r = dir->SetName(&name);
   125 			CheckForLeaveAfterOpenL(r, aRequest, h);
   126 			break;
   127 			}
   128 		}
   129 	
   130 	TPtrC8 pH((TUint8*)&h,sizeof(TInt));
   131 	TRAP(r,aRequest->WriteL(KMsgPtr3,pH))
   132 	CheckForLeaveAfterOpenL(r, aRequest, h);
   133 	aRequest->Session()->IncResourceCount();
   134 	return(KErrNone);
   135 	}
   136 
   137 
   138 TInt TFsDirOpen::Initialise(CFsRequest* aRequest)
   139 //
   140 //
   141 //	
   142 	{
   143 	
   144 	TInt r=ParseSubstPtr0(aRequest,aRequest->Src());
   145 	if (r!=KErrNone)
   146 		return(r);
   147 	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysDirOpen,&KCapFsPriDirOpen, __PLATSEC_DIAGNOSTIC_STRING("Dir Open"));
   148 	if(r != KErrNone)
   149 		return r;
   150 	return KErrNone;
   151 	}
   152 
   153 
   154 TInt TFsDirReadOne::DoRequestL(CFsRequest* aRequest)
   155 //
   156 // Read one directory entry.
   157 //
   158 	{
   159 	__PRINT(_L("TFsDirReadOne::DoRequestL(CFsRequest* aRequest)"));
   160 	CDirCB* dir=(CDirCB*)aRequest->ScratchValue();
   161 	TInt r=dir->CheckMount();
   162 	if (r!=KErrNone)
   163 		return(r);
   164 	TEntry e;
   165 
   166 	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &dir);
   167 	TRAP(r,dir->ReadL(e))
   168 	TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, 
   169 		KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize);
   170 
   171 
   172 	if (r==KErrNone)
   173 		{
   174 		TPckgC<TEntry> pE(e);
   175 		aRequest->WriteL(KMsgPtr0,pE);
   176 		}
   177 	return(r);
   178 	}
   179 
   180 TInt TFsDirReadOne::Initialise(CFsRequest* aRequest)
   181 //
   182 //
   183 //	
   184 	{
   185 	return(DoInitialise(aRequest));
   186 	}
   187 
   188 TInt TFsDirReadPacked::DoRequestL(CFsRequest* aRequest)
   189 //
   190 // Read packed directory entries.
   191 //
   192 	{
   193 
   194 	__PRINT(_L("TFsDirReadPacked::DoRequestL(CFsRequest* aRequest)"));
   195 	CDirCB* dir=(CDirCB*)aRequest->ScratchValue();
   196 	TInt r=dir->CheckMount();
   197 	if (r!=KErrNone)
   198 		return(r);
   199 
   200 	TBuf8<KEntryArraySize> buf;
   201 	TEntry* pE=(TEntry*)buf.Ptr();
   202 	TEntry* pEnd=PtrAdd(pE,KEntryArraySize);
   203 	volatile TInt len=0;
   204 	TRAP(r,fsDirReadPacked(pE,pEnd,len,*(dir)));
   205 	buf.SetLength(len);
   206 	aRequest->WriteL(KMsgPtr0,buf);
   207 	return(r);
   208 	}
   209 
   210 TInt TFsDirReadPacked::Initialise(CFsRequest* aRequest)
   211 //
   212 //	Call GetDirFromHandle to determine asynchronicity ***
   213 //	
   214 	{
   215 	return(DoInitialise(aRequest));
   216 	}
   217 
   218 
   219 
   220 
   221 /**
   222 Default cosntructor.
   223 */
   224 EXPORT_C CDirCB::CDirCB()
   225 	{
   226 
   227 //	iPending=EFalse;
   228 //	iDrive=NULL;
   229 //	iMount=NULL;
   230 	}
   231 
   232 
   233 
   234 
   235 /**
   236 Destructor.
   237 
   238 Frees resources before destruction of the object.
   239 */
   240 EXPORT_C CDirCB::~CDirCB()
   241 	{
   242 	if(iMount)
   243 		{
   244 		RemoveResource(*iMount);
   245 		iMount->Close();
   246 		}
   247 	}
   248 
   249 TInt CDirCB::CheckMount()
   250 //
   251 // Check that the media is still mounted.
   252 //
   253 	{
   254 
   255 	TDrive& d=Drive();
   256 	TInt r=d.CheckMount();
   257 	if (r!=KErrNone)
   258 		return(r);
   259 	if (&Mount()!=&d.CurrentMount())
   260 		return(KErrDisMounted);
   261 	return(KErrNone);
   262 	}
   263 
   264 EXPORT_C void CDirCB::InitL(TDrive* aDrive)
   265 //
   266 // Initialise
   267 //
   268 	{
   269 	DoInitL(aDrive->DriveNumber());
   270 	iDrive=aDrive;
   271 	iMount=&aDrive->CurrentMount();
   272 	User::LeaveIfError(iMount->Open());
   273 	}
   274 
   275 
   276 
   277 
   278 /**
   279 Stores a long full entry name, a TEntry::iName value, into a buffer,
   280 re-allocating the buffer first, if necessary, to make it large enough.
   281 
   282 The function should be implemented by a derived class; this implementation
   283 is empty.
   284 
   285 This function is called by a file server reading successive entries,
   286 when the file server reads an entry for which the full file name is longer than
   287 the maximum buffer size. Once this function has been called, the iPending flag
   288 is set to true by the file server and, on the next call to ReadL(),
   289 the buffer created in this function is used to store the long entry name.
   290 
   291 The function should leave with an appropriate error code on error detection.
   292 
   293 @param aName The name to be set to a newly read entry.
   294 */
   295 EXPORT_C void CDirCB::StoreLongEntryNameL(const TDesC& /*aName*/)
   296 	{}
   297 
   298 	
   299 EXPORT_C TInt CDirCB::GetInterface(TInt /*aInterfaceId*/,TAny*& /*aInterface*/,TAny* /*aInput*/)
   300 	{
   301 	return(KErrNotSupported);
   302 	}
   303