| 0 |      1 | // Copyright (c) 2002-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_obj.cpp
 | 
|  |     15 | // 
 | 
|  |     16 | //
 | 
|  |     17 | 
 | 
|  |     18 | #include "sf_std.h"
 | 
|  |     19 | 
 | 
|  |     20 | const TInt KObjectIxGranularity=8;		
 | 
|  |     21 | const TInt KObjectConGranularity=8;
 | 
|  |     22 | const TInt KObjectConIxGranularity=4;
 | 
|  |     23 | const TInt KObjectIndexMask=0x7fff;
 | 
|  |     24 | const TInt KObjectMaxIndex=0x7fff;
 | 
|  |     25 | const TInt KObjectInstanceShift=16;
 | 
|  |     26 | const TInt KObjectInstanceMask=0x3fff;
 | 
|  |     27 | const TInt KObjectUniqueIDShift=16;
 | 
|  |     28 | const TInt KObjectIxMaxHandles=0x8000;
 | 
|  |     29 | 
 | 
|  |     30 | inline TInt index(TInt aHandle)
 | 
|  |     31 | 	{return(aHandle&KObjectIndexMask);}
 | 
|  |     32 | inline TInt instance(TInt aHandle)
 | 
|  |     33 | 	{return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
 | 
|  |     34 | inline TInt instanceLimit(TInt& aCount)
 | 
|  |     35 | 	{return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
 | 
|  |     36 | inline TInt makeHandle(TInt anIndex,TInt anInstance)
 | 
|  |     37 | 	{return((TInt)((anInstance<<KObjectInstanceShift)|anIndex));}
 | 
|  |     38 | 
 | 
|  |     39 | inline TInt uniqueID(TInt aHandle)
 | 
|  |     40 | 	{return((aHandle>>KObjectUniqueIDShift)&KObjectInstanceMask);}
 | 
|  |     41 | inline TInt makeFindHandle(TInt anIndex,TInt anUniqueID)
 | 
|  |     42 | 	{return((TInt)((anUniqueID<<KObjectUniqueIDShift)|anIndex));}
 | 
|  |     43 | 
 | 
|  |     44 | 
 | 
|  |     45 | CFsObjectConIx* CFsObjectConIx::NewL()
 | 
|  |     46 | //
 | 
|  |     47 | // Create an instance of this class.
 | 
|  |     48 | //
 | 
|  |     49 | 	{
 | 
|  |     50 | 
 | 
|  |     51 | 	return new(ELeave) CFsObjectConIx;
 | 
|  |     52 | 	}
 | 
|  |     53 | 
 | 
|  |     54 | CFsObjectConIx::CFsObjectConIx()
 | 
|  |     55 | //
 | 
|  |     56 | // Constructor
 | 
|  |     57 | //
 | 
|  |     58 | 	: iNextUniqueID(1)
 | 
|  |     59 | 	{
 | 
|  |     60 | 	}
 | 
|  |     61 | 
 | 
|  |     62 | CFsObjectConIx::~CFsObjectConIx()
 | 
|  |     63 | //
 | 
|  |     64 | // Destructor
 | 
|  |     65 | //
 | 
|  |     66 | 	{
 | 
|  |     67 | 	if (iCount)
 | 
|  |     68 | 		{
 | 
|  |     69 | 		TInt i=-1;
 | 
|  |     70 | 		while(++i<iCount)
 | 
|  |     71 | 			{
 | 
|  |     72 | 			CFsObjectCon* pS=iContainers[i];
 | 
|  |     73 | 			delete pS;
 | 
|  |     74 | 			}
 | 
|  |     75 | 		}
 | 
|  |     76 | 	delete iContainers;
 | 
|  |     77 | 	}
 | 
|  |     78 | 
 | 
|  |     79 | void CFsObjectConIx::CreateContainerL(CFsObjectCon*& aContainer)
 | 
|  |     80 | //
 | 
|  |     81 | // Actually create the container
 | 
|  |     82 | //
 | 
|  |     83 | 	{
 | 
|  |     84 | 
 | 
|  |     85 | 	aContainer=CFsObjectCon::NewL();
 | 
|  |     86 | 	aContainer->iUniqueID=iNextUniqueID;
 | 
|  |     87 | 	if (iCount==iAllocated)
 | 
|  |     88 | 		{
 | 
|  |     89 | 		TInt newAlloc=iAllocated+KObjectConIxGranularity;
 | 
|  |     90 | 		iContainers=(CFsObjectCon**)User::ReAllocL(iContainers, newAlloc*sizeof(CFsObjectCon*));
 | 
|  |     91 | 		iAllocated=newAlloc;
 | 
|  |     92 | 		}
 | 
|  |     93 | 	iContainers[iCount++]=aContainer;
 | 
|  |     94 | 	}
 | 
|  |     95 | 
 | 
|  |     96 | CFsObjectCon* CFsObjectConIx::CreateL()
 | 
|  |     97 | //
 | 
|  |     98 | // Create a new container.
 | 
|  |     99 | //
 | 
|  |    100 | 	{
 | 
|  |    101 | 
 | 
|  |    102 | 	CFsObjectCon* pC=NULL;
 | 
|  |    103 | 	TRAPD(r,CreateContainerL(pC))
 | 
|  |    104 | 	if (r!=KErrNone)
 | 
|  |    105 | 		{
 | 
|  |    106 | 		delete pC;
 | 
|  |    107 | 		User::Leave(r);
 | 
|  |    108 | 		}
 | 
|  |    109 | 	iNextUniqueID++;
 | 
|  |    110 | 	return pC;
 | 
|  |    111 | 	}
 | 
|  |    112 | 
 | 
|  |    113 | void CFsObjectConIx::Remove(CFsObjectCon* aCon)
 | 
|  |    114 | //
 | 
|  |    115 | // Remove a container from the index.
 | 
|  |    116 | //
 | 
|  |    117 | 	{
 | 
|  |    118 | 	if (!aCon)
 | 
|  |    119 | 		return;
 | 
|  |    120 | 	CFsObjectCon** pS=iContainers;
 | 
|  |    121 | 	CFsObjectCon** pE=pS+iCount;
 | 
|  |    122 | 	while(pS<pE)
 | 
|  |    123 | 		{
 | 
|  |    124 | 		if (*pS==aCon)
 | 
|  |    125 | 			{
 | 
|  |    126 | 			Mem::Move((TAny*)pS,(TAny*)(pS+1),TInt(pE)-TInt(pS)-sizeof(CFsObjectCon*));
 | 
|  |    127 | 			TInt newAlloc=--iCount;
 | 
|  |    128 | 			newAlloc=(newAlloc+(KObjectConIxGranularity-1))&~(KObjectConIxGranularity-1);
 | 
|  |    129 | 			if (newAlloc!=iAllocated)
 | 
|  |    130 | 				{
 | 
|  |    131 | 				if (newAlloc)
 | 
|  |    132 | 					iContainers=(CFsObjectCon**)User::ReAlloc(iContainers,newAlloc*sizeof(CFsObjectCon*));
 | 
|  |    133 | 				else
 | 
|  |    134 | 					{
 | 
|  |    135 | 					delete iContainers;
 | 
|  |    136 | 					iContainers=NULL;
 | 
|  |    137 | 					}
 | 
|  |    138 | 				iAllocated=newAlloc;
 | 
|  |    139 | 				}
 | 
|  |    140 | 			delete aCon;
 | 
|  |    141 | 			return;
 | 
|  |    142 | 			}
 | 
|  |    143 | 		pS++;
 | 
|  |    144 | 		}
 | 
|  |    145 | 	Fault(EObjRemoveContainerNotFound);
 | 
|  |    146 | 	}
 | 
|  |    147 | 
 | 
|  |    148 | 
 | 
|  |    149 | /**
 | 
|  |    150 | Constructs the object and initializes the reference count to one. 
 | 
|  |    151 |  
 | 
|  |    152 | Once constructed, a reference counting object cannot be deleted until its 
 | 
|  |    153 | reference count is reduced to zero. 
 | 
|  |    154 |  
 | 
|  |    155 | @see CFsObject::Close
 | 
|  |    156 | */
 | 
|  |    157 | EXPORT_C CFsObject::CFsObject()
 | 
|  |    158 | 	{
 | 
|  |    159 | 
 | 
|  |    160 | //	iContainer=NULL;
 | 
|  |    161 | //	iName=NULL;
 | 
|  |    162 | 	iAccessCount=1;
 | 
|  |    163 | 	}
 | 
|  |    164 | 
 | 
|  |    165 | 
 | 
|  |    166 | /**
 | 
|  |    167 | Destructor.
 | 
|  |    168 |  
 | 
|  |    169 | Deallocates memory associated with this objects name, if a name 
 | 
|  |    170 | has been set.
 | 
|  |    171 |  
 | 
|  |    172 | @panic FSERV 104 if the reference count is not zero when
 | 
|  |    173 |        the destructor is called.
 | 
|  |    174 | */
 | 
|  |    175 | EXPORT_C  CFsObject::~CFsObject()
 | 
|  |    176 | 	{
 | 
|  |    177 | 	__PRINT1(_L("CFsObject::~CFsObject() 0x%x"),this);
 | 
|  |    178 | 	__ASSERT_ALWAYS(Dec()==0,Fault(EObjDestructorAccessCount));	
 | 
|  |    179 | 	__ASSERT_ALWAYS(!iContainer,Fault(EObjDestructorContainer));
 | 
|  |    180 | 	if(iName)
 | 
|  |    181 | 		User::Free(iName);
 | 
|  |    182 | 	}
 | 
|  |    183 | 
 | 
|  |    184 | 
 | 
|  |    185 | /**
 | 
|  |    186 | Opens this reference counting object.
 | 
|  |    187 | 
 | 
|  |    188 | The default behaviour increments the reference count by one. 
 | 
|  |    189 | 
 | 
|  |    190 | Where a derived class implements its own version of this function, it must 
 | 
|  |    191 | either use the protected member function Inc() to increment the reference 
 | 
|  |    192 | count or make a base call to this function.
 | 
|  |    193 | 
 | 
|  |    194 | @return KErrNone if successful.
 | 
|  |    195 |         KErrGeneral if unable to increment reference count.
 | 
|  |    196 | */
 | 
|  |    197 | 
 | 
|  |    198 | EXPORT_C TInt CFsObject::Open()
 | 
|  |    199 | 	{
 | 
|  |    200 | 	TInt count=Inc();
 | 
|  |    201 | 	__THRD_PRINT2(_L("CFsObject::Open() object=0x%x count=%d"),this,count);
 | 
|  |    202 | 	return(count?KErrNone:KErrGeneral);
 | 
|  |    203 | 	}
 | 
|  |    204 | 
 | 
|  |    205 | 
 | 
|  |    206 | /**
 | 
|  |    207 | Removes an assigned container object then deletes this reference
 | 
|  |    208 | counting object.
 | 
|  |    209 | */
 | 
|  |    210 | void CFsObject::DoClose()
 | 
|  |    211 | 	{
 | 
|  |    212 | 	__THRD_PRINT(_L("CFsObject::DoClose()"));
 | 
|  |    213 | 	if(iContainer)
 | 
|  |    214 | 		{
 | 
|  |    215 | 		iContainer->Remove(this,ETrue);
 | 
|  |    216 | 		iContainer=NULL;
 | 
|  |    217 | 		}
 | 
|  |    218 | 	delete(this);
 | 
|  |    219 | 	}
 | 
|  |    220 | 
 | 
|  |    221 | 
 | 
|  |    222 | /**
 | 
|  |    223 | Closes this reference counting object.
 | 
|  |    224 | 
 | 
|  |    225 | The default behaviour decrements the reference count by one. If this becomes 
 | 
|  |    226 | zero, then the function calls DoClose on this reference counting object.
 | 
|  |    227 |  
 | 
|  |    228 | Where a derived class implements its own version of this function, it can 
 | 
|  |    229 | use the protected member functions Dec() & DoClose() or make a base call to 
 | 
|  |    230 | this function.
 | 
|  |    231 | 
 | 
|  |    232 | @see CFsObject::DoClose
 | 
|  |    233 | */
 | 
|  |    234 | EXPORT_C void CFsObject::Close()
 | 
|  |    235 | 	{
 | 
|  |    236 | 	__THRD_PRINT(_L("CFsObject::Close()"));
 | 
|  |    237 | 	if(Dec()==1)
 | 
|  |    238 | 		DoClose();
 | 
|  |    239 | 	}
 | 
|  |    240 | 
 | 
|  |    241 | 
 | 
|  |    242 | /**
 | 
|  |    243 | Determine if this object is within the correct drive thread context 
 | 
|  |    244 | for file based operations.
 | 
|  |    245 | 
 | 
|  |    246 | The default behaviour is to return True.
 | 
|  |    247 | 
 | 
|  |    248 | A derived class implementation is required.
 | 
|  |    249 | 
 | 
|  |    250 | @return ETrue
 | 
|  |    251 | */
 | 
|  |    252 | EXPORT_C TBool CFsObject::IsCorrectThread()
 | 
|  |    253 | 	{
 | 
|  |    254 | 	return(ETrue);
 | 
|  |    255 | 	}
 | 
|  |    256 | 
 | 
|  |    257 | 
 | 
|  |    258 | 
 | 
|  |    259 | /**
 | 
|  |    260 | Sets or clears this reference counting object's name.
 | 
|  |    261 | 
 | 
|  |    262 | To set the name, the specified descriptor must contain the name to be set. 
 | 
|  |    263 | Once the name has been successfully set, then the specified source descriptor 
 | 
|  |    264 | can be discarded.
 | 
|  |    265 | 
 | 
|  |    266 | To clear an existing name, specify a NULL argument.
 | 
|  |    267 | 
 | 
|  |    268 | @param aName A pointer to the descriptor containing the name to be set, or 
 | 
|  |    269 |              NULL if an existing name is to be cleared.
 | 
|  |    270 | 
 | 
|  |    271 | @return KErrNone if the function is successful;
 | 
|  |    272 |         KErrNoMemory if there is insufficient memory available.
 | 
|  |    273 | 
 | 
|  |    274 | @panic USER 11 if the length of aName is greater than KMaxName
 | 
|  |    275 |        for a 16-bit descriptor.
 | 
|  |    276 | @panic USER 23 if the length of aName is greater than KMaxName
 | 
|  |    277 |        for an 8-bit descriptor.
 | 
|  |    278 | */
 | 
|  |    279 | EXPORT_C TInt CFsObject::SetName(const TDesC *aName)
 | 
|  |    280 | 	{
 | 
|  |    281 | 	User::Free(iName);
 | 
|  |    282 | 	iName=NULL;
 | 
|  |    283 | 	if (aName!=NULL)
 | 
|  |    284 | 		{
 | 
|  |    285 | 		iName=aName->Alloc();
 | 
|  |    286 | 		if (iName==NULL)
 | 
|  |    287 | 			return(KErrNoMemory);
 | 
|  |    288 | 		}
 | 
|  |    289 | 	return(KErrNone);
 | 
|  |    290 | 	}
 | 
|  |    291 | 
 | 
|  |    292 | 
 | 
|  |    293 | /**
 | 
|  |    294 | Gets the name of this reference counting object.
 | 
|  |    295 | 
 | 
|  |    296 | The default behaviour provided by this function depends on whether a name 
 | 
|  |    297 | has been explicitly set into the object:
 | 
|  |    298 | 
 | 
|  |    299 | If a name has previously been set, then the function returns that name.
 | 
|  |    300 | 
 | 
|  |    301 | If a name has not been set, then the function returns NULL.
 | 
|  |    302 | 
 | 
|  |    303 | @return A modifiable buffer descriptor with a defined maximum length containing 
 | 
|  |    304 |         the name of this reference counting object or a TName with no contents.
 | 
|  |    305 | */
 | 
|  |    306 | EXPORT_C TName CFsObject::Name() const
 | 
|  |    307 | 	{
 | 
|  |    308 | 	if (iName)
 | 
|  |    309 | 		return(*iName);
 | 
|  |    310 | 	
 | 
|  |    311 | 	TName empty;
 | 
|  |    312 | 	return empty;
 | 
|  |    313 | 	}
 | 
|  |    314 | 
 | 
|  |    315 | 
 | 
|  |    316 | /**
 | 
|  |    317 | Gets the Unique ID of the assigned object container to this object.
 | 
|  |    318 | 
 | 
|  |    319 | @return A unique number for file system container objects.
 | 
|  |    320 | */
 | 
|  |    321 | TInt CFsObject::UniqueID() const {return(iContainer->UniqueID());}
 | 
|  |    322 | 
 | 
|  |    323 | 
 | 
|  |    324 | CFsObjectIx* CFsObjectIx::NewL()
 | 
|  |    325 | //
 | 
|  |    326 | // Create an instance of this class.
 | 
|  |    327 | //
 | 
|  |    328 | 	{
 | 
|  |    329 | 	CFsObjectIx* pO=new(ELeave) CFsObjectIx;
 | 
|  |    330 | 	TInt r=pO->iLock.CreateLocal();
 | 
|  |    331 | 	if(r!=KErrNone)
 | 
|  |    332 | 		{
 | 
|  |    333 | 		delete(pO);
 | 
|  |    334 | 		User::Leave(r);
 | 
|  |    335 | 		}
 | 
|  |    336 | 	return(pO);
 | 
|  |    337 | 	}
 | 
|  |    338 | 
 | 
|  |    339 | CFsObjectIx::CFsObjectIx()
 | 
|  |    340 | //
 | 
|  |    341 | // Constructor
 | 
|  |    342 | //
 | 
|  |    343 | 	: iNextInstance(1)
 | 
|  |    344 | 	{
 | 
|  |    345 | //	iAllocated=0;
 | 
|  |    346 | //	iNumEntries=0;
 | 
|  |    347 | //	iHighWaterMark=0;
 | 
|  |    348 | //	iObjects=NULL;
 | 
|  |    349 | 	}
 | 
|  |    350 | 
 | 
|  |    351 | 
 | 
|  |    352 | /**
 | 
|  |    353 |     Close all objects that were created in the main file server thread.
 | 
|  |    354 |     For sync. drives all objects must be closed in the main file server thread, because
 | 
|  |    355 |     they are created in this thread, as soon as all synch. requests are processed there.
 | 
|  |    356 | */
 | 
|  |    357 | void CFsObjectIx::CloseMainThreadObjects()
 | 
|  |    358 | 	{
 | 
|  |    359 | 	__ASSERT_DEBUG(FsThreadManager::IsMainThread(),Fault(EObjectIxMainThread));
 | 
|  |    360 | 	__PRINT(_L("CFsObjectIx::CloseThreadObjects()"));
 | 
|  |    361 |     
 | 
|  |    362 | 	Lock();
 | 
|  |    363 | 	// We have to be very careful here. Calling Close() on the objects in the array
 | 
|  |    364 | 	// may result in other entries being removed from the array before we delete
 | 
|  |    365 | 	// them here, and may result in the array being ReAlloc()ed, corrupting the removed
 | 
|  |    366 | 	// entries, hence we must check the iHighWaterMark value each time round the loop.
 | 
|  |    367 | 	TInt i=-1;
 | 
|  |    368 | 	while(++i<iHighWaterMark)
 | 
|  |    369 | 		{
 | 
|  |    370 | 		SFsObjectIxRec* pS=iObjects+i;
 | 
|  |    371 | 		CFsObject *pO=pS->obj;
 | 
|  |    372 | 		if (pO && pO->IsCorrectThread())
 | 
|  |    373 | 			{
 | 
|  |    374 | 			// invalidate entry before closing it
 | 
|  |    375 | 			pS->obj=NULL;
 | 
|  |    376 | 			pO->Close();	
 | 
|  |    377 | 			}
 | 
|  |    378 | 		}
 | 
|  |    379 | 	Unlock();
 | 
|  |    380 | 	}
 | 
|  |    381 | 
 | 
|  |    382 | 
 | 
|  |    383 | CFsObjectIx::~CFsObjectIx()
 | 
|  |    384 | //
 | 
|  |    385 | // Destructor
 | 
|  |    386 | // Assumes that no need to lock
 | 
|  |    387 | //
 | 
|  |    388 | 	{
 | 
|  |    389 | 	__PRINT1(_L("CFsObjectIx::~CFsObjectIx() 0x%x"),this);
 | 
|  |    390 |     
 | 
|  |    391 | 	// We have to be very careful here. Calling Close() on the objects in the array
 | 
|  |    392 | 	// may result in other entries being removed from the array before we delete
 | 
|  |    393 | 	// them here, and may result in the array being ReAlloc()ed, corrupting the removed
 | 
|  |    394 | 	// entries, hence we must check the iHighWaterMark value each time round the loop.
 | 
|  |    395 | 	TInt i=-1;
 | 
|  |    396 | 	while(++i<iHighWaterMark)
 | 
|  |    397 | 		{
 | 
|  |    398 | 		SFsObjectIxRec* pS=iObjects+i;
 | 
|  |    399 | 		CFsObject *pO=pS->obj;
 | 
|  |    400 | 		if (pO)
 | 
|  |    401 | 			{
 | 
|  |    402 | 			// invalidate entry before closing it
 | 
|  |    403 | 			pS->obj=NULL;
 | 
|  |    404 | 			pO->Close();	
 | 
|  |    405 | 			}
 | 
|  |    406 | 		}
 | 
|  |    407 | 	delete iObjects;
 | 
|  |    408 | 	iLock.Close();
 | 
|  |    409 | 	}
 | 
|  |    410 | 
 | 
|  |    411 | TInt CFsObjectIx::AddL(CFsObject* anObj,TBool aLock)
 | 
|  |    412 | //
 | 
|  |    413 | // Add a new object to the index.
 | 
|  |    414 | //
 | 
|  |    415 | 	{
 | 
|  |    416 | 	if(aLock)
 | 
|  |    417 | 		Lock();
 | 
|  |    418 | 	SFsObjectIxRec *pS=iObjects;
 | 
|  |    419 | 	SFsObjectIxRec *pE=pS+iHighWaterMark;
 | 
|  |    420 | 	TInt i=0;
 | 
|  |    421 | 	TInt inc=0;
 | 
|  |    422 | 	while(pS<pE && pS->obj)
 | 
|  |    423 | 		pS++, i++;
 | 
|  |    424 | 	if (pS==pE)
 | 
|  |    425 | 		inc=1;
 | 
|  |    426 | 	if (pS==pE && iAllocated==iHighWaterMark)
 | 
|  |    427 | 		{
 | 
|  |    428 | 		// no slots free, so reallocate array
 | 
|  |    429 | 		if (iHighWaterMark==KObjectIxMaxHandles)
 | 
|  |    430 | 			{
 | 
|  |    431 | 			if(aLock)
 | 
|  |    432 | 				Unlock();
 | 
|  |    433 | 			User::LeaveNoMemory();
 | 
|  |    434 | 			}
 | 
|  |    435 | 		TInt newAlloc=iAllocated + KObjectIxGranularity;
 | 
|  |    436 | 		SFsObjectIxRec* pA=(SFsObjectIxRec*)User::ReAlloc(iObjects, newAlloc*sizeof(SFsObjectIxRec));
 | 
|  |    437 | 		if(!pA)
 | 
|  |    438 | 			{
 | 
|  |    439 | 			if(aLock)
 | 
|  |    440 | 				Unlock();
 | 
|  |    441 | 			User::Leave(KErrNoMemory);
 | 
|  |    442 | 			}
 | 
|  |    443 | 		iObjects=pA;
 | 
|  |    444 | 		iAllocated=newAlloc;
 | 
|  |    445 | 		i=iHighWaterMark;
 | 
|  |    446 | 		pS=pA+i;
 | 
|  |    447 | 		}
 | 
|  |    448 | 	pS->obj=anObj;
 | 
|  |    449 | 	pS->uniqueID=(TUint16)anObj->UniqueID();
 | 
|  |    450 | 	pS->instance=(TUint16)instanceLimit(iNextInstance);
 | 
|  |    451 | 	iNextInstance++;
 | 
|  |    452 | 	iHighWaterMark+=inc;
 | 
|  |    453 | 	++iNumEntries;
 | 
|  |    454 | 	TInt h=makeHandle(i,pS->instance);
 | 
|  |    455 | 	if(aLock)
 | 
|  |    456 | 		Unlock();
 | 
|  |    457 | 	return(h);
 | 
|  |    458 | 	}
 | 
|  |    459 | 
 | 
|  |    460 | void CFsObjectIx::Remove(TInt aHandle,TBool aLock)
 | 
|  |    461 | //
 | 
|  |    462 | // Remove an object from the index.
 | 
|  |    463 | //
 | 
|  |    464 | 	{
 | 
|  |    465 | 	if(aLock)
 | 
|  |    466 | 		Lock();
 | 
|  |    467 | 	TInt i=index(aHandle);
 | 
|  |    468 | 	__ASSERT_ALWAYS(i<iHighWaterMark,Fault(EObjRemoveBadHandle));
 | 
|  |    469 | 	SFsObjectIxRec* pR=iObjects+i;
 | 
|  |    470 | 	CFsObject *pO=pR->obj;
 | 
|  |    471 | 	if (!pO || pR->instance!=instance(aHandle) || pR->uniqueID!=pO->UniqueID())
 | 
|  |    472 | 		Fault(EObjRemoveBadHandle);
 | 
|  |    473 | 	pR->obj=NULL;
 | 
|  |    474 | 	--iNumEntries;
 | 
|  |    475 | 	if (i==iHighWaterMark-1)
 | 
|  |    476 | 		{
 | 
|  |    477 | 		do
 | 
|  |    478 | 			{
 | 
|  |    479 | 			i--;
 | 
|  |    480 | 			pR--;
 | 
|  |    481 | 			} while(i>=0 && !pR->obj);
 | 
|  |    482 | 		TInt newAlloc=(i+KObjectIxGranularity)&~(KObjectIxGranularity-1);
 | 
|  |    483 | 		if (newAlloc!=iAllocated)
 | 
|  |    484 | 			{
 | 
|  |    485 | 			if (newAlloc)
 | 
|  |    486 | 				iObjects=(SFsObjectIxRec*)User::ReAlloc(iObjects,newAlloc*sizeof(SFsObjectIxRec));
 | 
|  |    487 | 			else
 | 
|  |    488 | 				{
 | 
|  |    489 | 				delete iObjects;
 | 
|  |    490 | 				iObjects=NULL;
 | 
|  |    491 | 				}
 | 
|  |    492 | 			iAllocated=newAlloc;
 | 
|  |    493 | 			}
 | 
|  |    494 | 		iHighWaterMark=i+1;
 | 
|  |    495 | 		}
 | 
|  |    496 | 	if(aLock)
 | 
|  |    497 | 		Unlock();
 | 
|  |    498 | 	pO->Close();
 | 
|  |    499 | 	}
 | 
|  |    500 | 
 | 
|  |    501 | CFsObject *CFsObjectIx::At(TInt aHandle,TInt aUniqueID,TBool aLock)
 | 
|  |    502 | //
 | 
|  |    503 | // Return the object from its handle.
 | 
|  |    504 | //
 | 
|  |    505 | 	{
 | 
|  |    506 | 	if(aLock)
 | 
|  |    507 | 		Lock();
 | 
|  |    508 | 	TInt i=index(aHandle);
 | 
|  |    509 | 	if (i>=iHighWaterMark)
 | 
|  |    510 | 		{
 | 
|  |    511 | 		if(aLock)
 | 
|  |    512 | 			Unlock();
 | 
|  |    513 | 		return NULL;
 | 
|  |    514 | 		}
 | 
|  |    515 | 	SFsObjectIxRec *pS=iObjects+i;
 | 
|  |    516 | 	if (pS->instance!=instance(aHandle) || pS->uniqueID!=aUniqueID)
 | 
|  |    517 | 		{
 | 
|  |    518 | 		if(aLock)
 | 
|  |    519 | 			Unlock();
 | 
|  |    520 | 		return NULL;
 | 
|  |    521 | 		}
 | 
|  |    522 | 	if(aLock)
 | 
|  |    523 | 		Unlock();
 | 
|  |    524 | 	return pS->obj;	
 | 
|  |    525 | 	}
 | 
|  |    526 | 
 | 
|  |    527 | CFsObject *CFsObjectIx::At(TInt aHandle,TBool aLock)
 | 
|  |    528 | //
 | 
|  |    529 | // Return the object from its handle.
 | 
|  |    530 | //
 | 
|  |    531 | 	{
 | 
|  |    532 | 	if(aLock)
 | 
|  |    533 | 		Lock();
 | 
|  |    534 | 	TInt i=index(aHandle);
 | 
|  |    535 | 	if (i>=iHighWaterMark)
 | 
|  |    536 | 		{
 | 
|  |    537 | 		if(aLock)
 | 
|  |    538 | 			Unlock();
 | 
|  |    539 | 		return NULL;
 | 
|  |    540 | 		}
 | 
|  |    541 | 	SFsObjectIxRec *pS=iObjects+i;
 | 
|  |    542 | 	if (pS->instance!=instance(aHandle))
 | 
|  |    543 | 		{
 | 
|  |    544 | 		if(aLock)
 | 
|  |    545 | 			Unlock();
 | 
|  |    546 | 		return NULL;
 | 
|  |    547 | 		}
 | 
|  |    548 | 	if(aLock)
 | 
|  |    549 | 		Unlock();
 | 
|  |    550 | 	return pS->obj;
 | 
|  |    551 | 	}
 | 
|  |    552 | 
 | 
|  |    553 | TInt CFsObjectIx::At(const CFsObject* anObj,TBool aLock)
 | 
|  |    554 | //
 | 
|  |    555 | // Return the handle from an object.
 | 
|  |    556 | //
 | 
|  |    557 | 	{
 | 
|  |    558 | 	if(aLock)
 | 
|  |    559 | 		Lock();
 | 
|  |    560 | 	if (iHighWaterMark)
 | 
|  |    561 | 		{
 | 
|  |    562 | 		SFsObjectIxRec* pS=iObjects;
 | 
|  |    563 | 		SFsObjectIxRec* pE=pS+iHighWaterMark;
 | 
|  |    564 | 		TInt i=0;
 | 
|  |    565 | 		while(pS<pE && pS->obj!=anObj)
 | 
|  |    566 | 			pS++, i++;
 | 
|  |    567 | 		if (pS<pE)
 | 
|  |    568 | 			{
 | 
|  |    569 | 			TInt h=makeHandle(i,pS->instance);
 | 
|  |    570 | 			if(aLock)
 | 
|  |    571 | 				Unlock();	
 | 
|  |    572 | 			return(h);	
 | 
|  |    573 | 			}
 | 
|  |    574 | 		}
 | 
|  |    575 | 	if(aLock)
 | 
|  |    576 | 		Unlock();
 | 
|  |    577 | 	return KErrNotFound;
 | 
|  |    578 | 	}
 | 
|  |    579 | 
 | 
|  |    580 | 
 | 
|  |    581 | CFsObject* CFsObjectIx::operator[](TInt anIndex)
 | 
|  |    582 | //
 | 
|  |    583 | // Return the object at anIndex
 | 
|  |    584 | //
 | 
|  |    585 | 	{
 | 
|  |    586 | 
 | 
|  |    587 | 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iHighWaterMark,Fault(EArrayIndexOutOfRange));
 | 
|  |    588 | 	return iObjects[anIndex].obj;
 | 
|  |    589 | 	}
 | 
|  |    590 | 
 | 
|  |    591 | CFsObjectCon* CFsObjectCon::NewL()
 | 
|  |    592 | //
 | 
|  |    593 | // Create a new instance of this class.
 | 
|  |    594 | //
 | 
|  |    595 | 	{
 | 
|  |    596 | 	CFsObjectCon* pO=new(ELeave) CFsObjectCon(ENotOwnerID);
 | 
|  |    597 | 	TInt r=pO->iLock.CreateLocal();
 | 
|  |    598 | 	if(r!=KErrNone)
 | 
|  |    599 | 		{
 | 
|  |    600 | 		delete(pO);
 | 
|  |    601 | 		User::Leave(r);
 | 
|  |    602 | 		}
 | 
|  |    603 | 	return(pO);
 | 
|  |    604 | 	}
 | 
|  |    605 | 
 | 
|  |    606 | CFsObjectCon::CFsObjectCon(TInt aUniqueID)
 | 
|  |    607 | //
 | 
|  |    608 | // Constructor
 | 
|  |    609 | //
 | 
|  |    610 | 	: iUniqueID(aUniqueID)
 | 
|  |    611 | 	{
 | 
|  |    612 | //	iAllocated=0;
 | 
|  |    613 | //	iCount=0;
 | 
|  |    614 | //	iObjects=NULL;
 | 
|  |    615 | 	}
 | 
|  |    616 | 
 | 
|  |    617 | CFsObjectCon::~CFsObjectCon()
 | 
|  |    618 | //
 | 
|  |    619 | // Destructor
 | 
|  |    620 | //
 | 
|  |    621 | 	{
 | 
|  |    622 | 	__ASSERT_ALWAYS(iCount==0,Fault(EObjectConDestructor));
 | 
|  |    623 | 	iLock.Close();
 | 
|  |    624 | 	delete iObjects;
 | 
|  |    625 | 	}
 | 
|  |    626 | 
 | 
|  |    627 | void CFsObjectCon::AddL(CFsObject* anObj,TBool aLock)
 | 
|  |    628 | //
 | 
|  |    629 | // Install a new object to the container. The full name must be unique.
 | 
|  |    630 | //
 | 
|  |    631 | 	{
 | 
|  |    632 | 	if(anObj->iName)
 | 
|  |    633 | 		User::LeaveIfError(CheckUniqueName(anObj));
 | 
|  |    634 | 	if(aLock)
 | 
|  |    635 | 		Lock();
 | 
|  |    636 | 	if (iCount==iAllocated)
 | 
|  |    637 | 		{
 | 
|  |    638 | 		TInt newAlloc=iAllocated+KObjectConGranularity;
 | 
|  |    639 | 		CFsObject** pO=(CFsObject**)User::ReAlloc(iObjects, newAlloc*sizeof(CFsObject*));
 | 
|  |    640 | 		if(!pO)
 | 
|  |    641 | 			{
 | 
|  |    642 | 			if(aLock)
 | 
|  |    643 | 				Unlock();
 | 
|  |    644 | 			User::Leave(KErrNoMemory);
 | 
|  |    645 | 			}
 | 
|  |    646 | 		iObjects=pO;
 | 
|  |    647 | 		iAllocated=newAlloc;
 | 
|  |    648 | 		}
 | 
|  |    649 | 	iObjects[iCount++]=anObj;
 | 
|  |    650 | 	if (iUniqueID!=ENotOwnerID)
 | 
|  |    651 | 		anObj->iContainer=this;
 | 
|  |    652 | 	if(aLock)
 | 
|  |    653 | 		Unlock();
 | 
|  |    654 | 	}
 | 
|  |    655 | 
 | 
|  |    656 | void CFsObjectCon::Remove(CFsObject *anObj,TBool aLock)	
 | 
|  |    657 | //
 | 
|  |    658 | // Remove an object from the container.
 | 
|  |    659 | // This assumes that close is called by the calling function
 | 
|  |    660 | // 
 | 
|  |    661 | 	{
 | 
|  |    662 | 	if(aLock)
 | 
|  |    663 | 		Lock();
 | 
|  |    664 | 	CFsObject** pS=iObjects;
 | 
|  |    665 | 	CFsObject** pE=pS+iCount;
 | 
|  |    666 | 	while(pS<pE)
 | 
|  |    667 | 		{
 | 
|  |    668 | 		if (*pS==anObj)
 | 
|  |    669 | 			{
 | 
|  |    670 | 			Mem::Move((TAny*)pS,(TAny*)(pS+1),TInt(pE)-TInt(pS)-sizeof(CFsObject*));
 | 
|  |    671 | 			TInt newAlloc=--iCount;
 | 
|  |    672 | 			newAlloc=(newAlloc+(KObjectConGranularity-1))&~(KObjectConGranularity-1);
 | 
|  |    673 | 			if (newAlloc!=iAllocated)
 | 
|  |    674 | 				{
 | 
|  |    675 | 				if (newAlloc)
 | 
|  |    676 | 					iObjects=(CFsObject**)User::ReAlloc(iObjects,newAlloc*sizeof(CFsObject*));
 | 
|  |    677 | 				else
 | 
|  |    678 | 					{
 | 
|  |    679 | 					delete iObjects;
 | 
|  |    680 | 					iObjects=NULL;
 | 
|  |    681 | 					}
 | 
|  |    682 | 				iAllocated=newAlloc;
 | 
|  |    683 | 				}
 | 
|  |    684 | 			if(aLock)
 | 
|  |    685 | 				Unlock();
 | 
|  |    686 | 			anObj->iContainer = NULL;
 | 
|  |    687 | 			return;
 | 
|  |    688 | 			}
 | 
|  |    689 | 		pS++;
 | 
|  |    690 | 		}
 | 
|  |    691 | 	Fault(EObjRemoveObjectNotFound);
 | 
|  |    692 | 	}
 | 
|  |    693 | 
 | 
|  |    694 | CFsObject *CFsObjectCon::operator[](TInt anIndex)
 | 
|  |    695 | //
 | 
|  |    696 | // Return the object at anIndex.
 | 
|  |    697 | //
 | 
|  |    698 | 	{
 | 
|  |    699 | 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount, Fault(EArrayIndexOutOfRange));
 | 
|  |    700 | 	return iObjects[anIndex];
 | 
|  |    701 | 	}
 | 
|  |    702 | 
 | 
|  |    703 | CFsObject *CFsObjectCon::At(TInt aFindHandle) const
 | 
|  |    704 | //
 | 
|  |    705 | // Return the object at aFindHandle.
 | 
|  |    706 | // Should only be used there is no other access to the CFsObject
 | 
|  |    707 | //
 | 
|  |    708 | 	{
 | 
|  |    709 | 
 | 
|  |    710 | 	__ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,Fault(EObjFindBadHandle));
 | 
|  |    711 | 	TInt ix=index(aFindHandle);
 | 
|  |    712 | 	__ASSERT_ALWAYS(ix<iCount,Fault(EObjFindIndexOutOfRange));
 | 
|  |    713 | 	return iObjects[ix];
 | 
|  |    714 | 	}
 | 
|  |    715 | 
 | 
|  |    716 | CFsObject *CFsObjectCon::AtL(TInt aFindHandle) const
 | 
|  |    717 | //
 | 
|  |    718 | // Return the object at aFindHandle.
 | 
|  |    719 | // Should only be used if no other access to the CFsObject
 | 
|  |    720 | //
 | 
|  |    721 | 	{
 | 
|  |    722 | 
 | 
|  |    723 | 	__ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,User::Leave(KErrBadHandle));
 | 
|  |    724 | 	TInt ix=index(aFindHandle);
 | 
|  |    725 | 	__ASSERT_ALWAYS(ix<iCount,User::Leave(KErrArgument));
 | 
|  |    726 | 	return iObjects[ix];
 | 
|  |    727 | 	}
 | 
|  |    728 | 
 | 
|  |    729 | LOCAL_C TInt validateName(const TDesC &aName)
 | 
|  |    730 | //
 | 
|  |    731 | // Return KErrBadName if the name is invalid.
 | 
|  |    732 | //
 | 
|  |    733 | 	{
 | 
|  |    734 | 
 | 
|  |    735 | 	if (aName.Locate('*')!=KErrNotFound || aName.Locate('?')!=KErrNotFound || aName.Locate(':')!=KErrNotFound)
 | 
|  |    736 | 		return(KErrBadName);
 | 
|  |    737 | 	return(KErrNone);
 | 
|  |    738 | 	}
 | 
|  |    739 | 
 | 
|  |    740 | 
 | 
|  |    741 | TBool CFsObjectCon::NamesMatch(const TName& anObjectName, const CFsObject* aCurrentObject) const
 | 
|  |    742 | //
 | 
|  |    743 | // 
 | 
|  |    744 | //
 | 
|  |    745 | 	{
 | 
|  |    746 | 
 | 
|  |    747 | 	if (aCurrentObject->iName==NULL) // current object has no name, therefore not the same
 | 
|  |    748 | 		return(EFalse);
 | 
|  |    749 | 	return(anObjectName.Compare(*aCurrentObject->iName)==0); // short names are different, therefore not the same
 | 
|  |    750 | 	}
 | 
|  |    751 | 
 | 
|  |    752 | TInt CFsObjectCon::CheckUniqueName(const CFsObject* anObject) const
 | 
|  |    753 | //
 | 
|  |    754 | // Returns KErrBadName if the name is invalid or
 | 
|  |    755 | // returns KErrAlreadyExists if the full name is not unique.
 | 
|  |    756 | //
 | 
|  |    757 | 	{
 | 
|  |    758 | 
 | 
|  |    759 | 	TName name(*(anObject->iName));
 | 
|  |    760 | 	TInt r=validateName(name);
 | 
|  |    761 | 	if (r!=KErrNone)
 | 
|  |    762 | 		return r;
 | 
|  |    763 | 
 | 
|  |    764 | 	if (!iCount)
 | 
|  |    765 | 		return KErrNone;
 | 
|  |    766 | 
 | 
|  |    767 | 	CFsObject** pS=iObjects;
 | 
|  |    768 | 	CFsObject** pE=pS+iCount;
 | 
|  |    769 | 
 | 
|  |    770 | 	// if it's name is null, just need to check it's not already there
 | 
|  |    771 | 	if (!anObject->iName)
 | 
|  |    772 | 		{
 | 
|  |    773 | 		do
 | 
|  |    774 | 			{
 | 
|  |    775 | 			if (*pS==anObject)
 | 
|  |    776 | 				return KErrAlreadyExists;
 | 
|  |    777 | 			} while(++pS<pE);
 | 
|  |    778 | 		return KErrNone;
 | 
|  |    779 | 		}
 | 
|  |    780 | 
 | 
|  |    781 | 	do
 | 
|  |    782 | 		{
 | 
|  |    783 | 		if (NamesMatch(name,*pS))
 | 
|  |    784 | 			return KErrAlreadyExists;
 | 
|  |    785 | 		} while(++pS<pE);
 | 
|  |    786 | 	return KErrNone;
 | 
|  |    787 | 	}
 | 
|  |    788 | 
 | 
|  |    789 | TInt CFsObjectCon::FindByName(TInt &aFindHandle,const TDesC &aMatch) const
 | 
|  |    790 | //
 | 
|  |    791 | // Find an object starting at aFindHandle which matches aMatch
 | 
|  |    792 | // just using the objects name.
 | 
|  |    793 | //
 | 
|  |    794 | 	{
 | 
|  |    795 | 
 | 
|  |    796 | 	if (!iCount)
 | 
|  |    797 | 		return KErrNotFound;
 | 
|  |    798 | 	TInt ix=0;
 | 
|  |    799 | 	if (aFindHandle!=0)
 | 
|  |    800 | 		{
 | 
|  |    801 | 		__ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,Fault(EObjFindBadHandle));
 | 
|  |    802 | 		ix=index(aFindHandle)+1;
 | 
|  |    803 | 		};
 | 
|  |    804 | 	CFsObject** pS=iObjects;
 | 
|  |    805 | 	CFsObject** pE=pS+iCount;
 | 
|  |    806 | 	pS+=ix;
 | 
|  |    807 | 	while(pS<pE)
 | 
|  |    808 | 		{
 | 
|  |    809 | 		TName name=*((*pS++)->iName);
 | 
|  |    810 | 		if (name.MatchF(aMatch)!=KErrNotFound)
 | 
|  |    811 | 			{
 | 
|  |    812 | 			aFindHandle=makeFindHandle(ix,iUniqueID);
 | 
|  |    813 | 			return KErrNone;
 | 
|  |    814 | 			}
 | 
|  |    815 | 		ix++;
 | 
|  |    816 | 		}
 | 
|  |    817 | 	aFindHandle=makeFindHandle(KObjectMaxIndex,iUniqueID);
 | 
|  |    818 | 	return KErrNotFound;
 | 
|  |    819 | 	}
 | 
|  |    820 | 
 | 
|  |    821 | /**
 | 
|  |    822 | Constructs the object and initializes the Drive number as an invalid drive. 
 | 
|  |    823 |  
 | 
|  |    824 | Once constructed, a dispatch object cannot be deleted until its reference 
 | 
|  |    825 | count is reduced to zero. 
 | 
|  |    826 |  
 | 
|  |    827 | @see CFsDispatchObject::Close
 | 
|  |    828 | */
 | 
|  |    829 | CFsDispatchObject::CFsDispatchObject()
 | 
|  |    830 | 	: iDriveNumber(-1) 
 | 
|  |    831 | 	{}
 | 
|  |    832 | 
 | 
|  |    833 | /**
 | 
|  |    834 | Initialises dispatch object
 | 
|  |    835 | 
 | 
|  |    836 | Creates an internal request and sets it as a file resource close operation.
 | 
|  |    837 | Initialises drive number as specified.
 | 
|  |    838 | 
 | 
|  |    839 | @param aDrvNumber Drive for which the request is intended.
 | 
|  |    840 | */
 | 
|  |    841 | void CFsDispatchObject::DoInitL(TInt aDrvNumber)
 | 
|  |    842 | 	{
 | 
|  |    843 | 	CFsInternalRequest* PR= new(ELeave) CFsInternalRequest;
 | 
|  |    844 | 	__THRD_PRINT1(_L("internal request = 0x%x"),PR);
 | 
|  |    845 | 	PR->Set(DispatchObjectCloseOp,NULL);
 | 
|  |    846 | 	iRequest = PR;
 | 
|  |    847 | 	iRequest->SetDriveNumber(aDrvNumber);
 | 
|  |    848 | 	iRequest->SetScratchValue((TUint)this);
 | 
|  |    849 | 	iDriveNumber=aDrvNumber;
 | 
|  |    850 | 	}
 | 
|  |    851 | 
 | 
|  |    852 | /**
 | 
|  |    853 | Closes this dispatch object.
 | 
|  |    854 | 
 | 
|  |    855 | Decrements the reference count by one. If this becomes zero then the request 
 | 
|  |    856 | will either call Dispatch() if currently not within the correct thread 
 | 
|  |    857 | context otherwise the function calls DoClose() on this dispatch object.
 | 
|  |    858 | 
 | 
|  |    859 | @see CFsDispatchObject::IsCorrectThread
 | 
|  |    860 |      CFsDispatchObject::Dispatch
 | 
|  |    861 |      CFsObject::DoClose
 | 
|  |    862 | */
 | 
|  |    863 | EXPORT_C void CFsDispatchObject::Close()
 | 
|  |    864 | 	{
 | 
|  |    865 | 	__THRD_PRINT1(_L("CFsDispatchObject::Close() 0x%x"),this);
 | 
|  |    866 | 	if(Dec()!=1)
 | 
|  |    867 | 		return;
 | 
|  |    868 | 	if(!IsCorrectThread())
 | 
|  |    869 | 		Dispatch();
 | 
|  |    870 | 	else
 | 
|  |    871 | 		DoClose();
 | 
|  |    872 | 	}
 | 
|  |    873 | 
 | 
|  |    874 | /**
 | 
|  |    875 | Destructor.
 | 
|  |    876 |  
 | 
|  |    877 | Deletes assigned CFsRequest object.
 | 
|  |    878 | */
 | 
|  |    879 | CFsDispatchObject::~CFsDispatchObject()
 | 
|  |    880 | 	{
 | 
|  |    881 | 	__THRD_PRINT(_L("CFsDispatchObject::~CFsDispatchObject()"));
 | 
|  |    882 | 	if(iRequest)
 | 
|  |    883 | 		delete(iRequest);
 | 
|  |    884 | 	}
 | 
|  |    885 | 
 | 
|  |    886 | /**
 | 
|  |    887 | Dispatches an assigned CFsRequest object.
 | 
|  |    888 | 
 | 
|  |    889 | @see CFsRequest::Dispatch()
 | 
|  |    890 | */
 | 
|  |    891 | void CFsDispatchObject::Dispatch()
 | 
|  |    892 | 	{
 | 
|  |    893 | 	__ASSERT_DEBUG(iRequest,Fault(EDispatchObjectDispatch));
 | 
|  |    894 | 	iRequest->Dispatch();
 | 
|  |    895 | 	}
 | 
|  |    896 | 
 | 
|  |    897 | 
 | 
|  |    898 | /**
 | 
|  |    899 | Determine if this object is within the correct drive thread context 
 | 
|  |    900 | for file resource request.
 | 
|  |    901 | For example subsession close request.
 | 
|  |    902 | 
 | 
|  |    903 | @return ETrue if within the correct drive thread context.
 | 
|  |    904 | */
 | 
|  |    905 | EXPORT_C TBool CFsDispatchObject::IsCorrectThread()
 | 
|  |    906 | 	{
 | 
|  |    907 | 	if(!iRequest)
 | 
|  |    908 | 		return(ETrue);
 | 
|  |    909 | 	FsThreadManager::LockDrive(iRequest->DriveNumber());
 | 
|  |    910 | 	TBool b;
 | 
|  |    911 | 	__ASSERT_ALWAYS(FsThreadManager::IsDriveAvailable(iRequest->DriveNumber(),EFalse) || FsThreadManager::IsMainThread(), Fault(EDispatchObjectThread));
 | 
|  |    912 | 	if(!FsThreadManager::IsDriveAvailable(iRequest->DriveNumber(),EFalse) && FsThreadManager::IsMainThread())
 | 
|  |    913 | 		b=ETrue;
 | 
|  |    914 | 	else if(FsThreadManager::IsDriveSync(iRequest->DriveNumber(),EFalse) && FsThreadManager::IsMainThread())
 | 
|  |    915 | 		b=ETrue;
 | 
|  |    916 | 	else
 | 
|  |    917 | 		b=FsThreadManager::IsDriveThread(iRequest->DriveNumber(),EFalse);
 | 
|  |    918 | 	FsThreadManager::UnlockDrive(iRequest->DriveNumber());
 | 
|  |    919 | 	return(b);
 | 
|  |    920 | 	}
 | 
|  |    921 | 
 | 
|  |    922 | TInt TFsCloseObject::Initialise(CFsRequest* /*aRequest*/)
 | 
|  |    923 | //
 | 
|  |    924 | //
 | 
|  |    925 | //
 | 
|  |    926 | 	{
 | 
|  |    927 | 	return(KErrNone);
 | 
|  |    928 | 	}
 | 
|  |    929 | 
 | 
|  |    930 | TInt TFsCloseObject::DoRequestL(CFsRequest* /*aRequest*/)
 | 
|  |    931 | //
 | 
|  |    932 | //
 | 
|  |    933 | //
 | 
|  |    934 | 	{
 | 
|  |    935 | 	__PRINT(_L("TFsCloseObject::DoRequestL()"));
 | 
|  |    936 | 	return(KErrNone);
 | 
|  |    937 | 	}
 | 
|  |    938 | 
 | 
|  |    939 | TInt TFsCloseObject::Complete(CFsRequest* aRequest)
 | 
|  |    940 | //
 | 
|  |    941 | //
 | 
|  |    942 | //
 | 
|  |    943 | 	{
 | 
|  |    944 | 	__PRINT(_L("TFsCloseObject::Complete()"));
 | 
|  |    945 | 	CFsDispatchObject* pO=(CFsDispatchObject*)aRequest->ScratchValue();
 | 
|  |    946 | 	// set CFsDispatchObject::iRequest to NULL since request will be deleted in Free()
 | 
|  |    947 | 	pO->iRequest=NULL;
 | 
|  |    948 | 	pO->DoClose();
 | 
|  |    949 | 	return(KErrNone);
 | 
|  |    950 | 	}
 | 
|  |    951 | 
 | 
|  |    952 | 
 |