userlibandfileserver/fileserver/sfile/sf_dir.cpp
changeset 0 a41df078684a
child 43 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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