os/kernelhwsrv/userlibandfileserver/fileserver/srofs/dircache.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <e32std.h>
sl@0
    17
#include <e32std_private.h>
sl@0
    18
#include "sr_rofs.h"
sl@0
    19
#include <rofs.h>
sl@0
    20
sl@0
    21
sl@0
    22
CDirectoryCache::CDirectoryCache( CRofsMountCB& aMount, CProxyDrive& aLocalDrive, const TRofsHeader& aHeader )
sl@0
    23
	: iMount( aMount ), iLocalDrive( aLocalDrive ), 
sl@0
    24
	iTreeMediaOffset( aHeader.iDirTreeOffset ),
sl@0
    25
	iTreeSize( aHeader.iDirTreeSize ),
sl@0
    26
	iFilesMediaOffset( aHeader.iDirFileEntriesOffset ),
sl@0
    27
	iFilesSize( aHeader.iDirFileEntriesSize )
sl@0
    28
	{
sl@0
    29
	}
sl@0
    30
sl@0
    31
CDirectoryCache::~CDirectoryCache()
sl@0
    32
	{
sl@0
    33
	delete iTreeBuffer;
sl@0
    34
	delete iFilesBuffer;
sl@0
    35
	}
sl@0
    36
	
sl@0
    37
void CDirectoryCache::ConstructL()
sl@0
    38
	{
sl@0
    39
	iTreeBuffer = HBufC8::NewL( iTreeSize );
sl@0
    40
	iFilesBuffer = HBufC8::NewL( iFilesSize );
sl@0
    41
sl@0
    42
	TPtr8 ptr = iTreeBuffer->Des();
sl@0
    43
	User::LeaveIfError( iLocalDrive.Read( iTreeMediaOffset, iTreeSize, ptr) );
sl@0
    44
	TPtr8 ptr2 = iFilesBuffer->Des();
sl@0
    45
	User::LeaveIfError( iLocalDrive.Read( iFilesMediaOffset, iFilesSize, ptr2) );
sl@0
    46
	}
sl@0
    47
sl@0
    48
sl@0
    49
void CDirectoryCache::FindLeafDirL(const TDesC& aName, const TRofsDir*& aDir) const
sl@0
    50
//
sl@0
    51
// Navigate the path to find the leaf directory, starting at aDir.
sl@0
    52
//
sl@0
    53
	{
sl@0
    54
sl@0
    55
	TLex lex(aName);
sl@0
    56
	TInt r;
sl@0
    57
	FOREVER
sl@0
    58
		{
sl@0
    59
		lex.Inc(); // Skip the file separator
sl@0
    60
		lex.Mark();
sl@0
    61
		r=lex.Remainder().Locate(KPathDelimiter);
sl@0
    62
		
sl@0
    63
		if ( KErrNotFound == r )
sl@0
    64
			{
sl@0
    65
			r=lex.Remainder().Length();
sl@0
    66
			}
sl@0
    67
		if ( 0 == r ) // End of the path
sl@0
    68
			{
sl@0
    69
			break;
sl@0
    70
			}
sl@0
    71
sl@0
    72
		lex.Inc(r); // Set the token length
sl@0
    73
		
sl@0
    74
		const TRofsEntry* subDirEntry = NULL;
sl@0
    75
		TInt r = DoBinaryFindSubDir(lex.MarkedToken(), KEntryAttDir|KEntryAttMatchExclusive, aDir, subDirEntry );
sl@0
    76
		if( KErrNone != r )
sl@0
    77
			{
sl@0
    78
			User::Leave( KErrPathNotFound );
sl@0
    79
			}
sl@0
    80
		__ASSERT_DEBUG( 0 != (subDirEntry->iAtt & KEntryAttDir ), CRofs::Panic( CRofs::EPanicEntryNotDir ));
sl@0
    81
		aDir = RofsDirFromSubDirEntry( subDirEntry );
sl@0
    82
		}
sl@0
    83
	}
sl@0
    84
sl@0
    85
TInt CDirectoryCache::DoBinaryFindSubDir(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aSubDirEntry ) const
sl@0
    86
	//
sl@0
    87
	// Scan the directory aDir looking for subdirectory aName using binary search.
sl@0
    88
	// aName cannot contain wildcards and aSubDirEntry should always be NULL.
sl@0
    89
	// If a matching entry is found writes pointer to the entry into aSubDirEntry
sl@0
    90
	// and returns KErrNone.
sl@0
    91
	//
sl@0
    92
	{
sl@0
    93
sl@0
    94
	if (aSubDirEntry != NULL)
sl@0
    95
		{
sl@0
    96
		return DoFindSubDir(aName, aAtt, aDir, aSubDirEntry);
sl@0
    97
		}
sl@0
    98
sl@0
    99
	TInt numDirs=GetDirCount(aDir);
sl@0
   100
	TInt topIndex=numDirs-1;
sl@0
   101
	TInt bottomIndex=0;
sl@0
   102
sl@0
   103
	TBool bFound=EFalse;
sl@0
   104
	TInt retVal=KErrNotFound;
sl@0
   105
	if(topIndex>=0)
sl@0
   106
		{
sl@0
   107
		TUint16* offsets = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
sl@0
   108
		offsets += 2; //to skip file and dir counts
sl@0
   109
sl@0
   110
		while((!bFound) && (topIndex>=bottomIndex))
sl@0
   111
		{
sl@0
   112
			TInt32 middleIndex;
sl@0
   113
			const TRofsEntry* pCurrentEntry=NULL;
sl@0
   114
			middleIndex=(topIndex+bottomIndex)>>1;
sl@0
   115
sl@0
   116
			//Offsets for directories are relative to the start of the
sl@0
   117
			//directory block
sl@0
   118
			TUint8* ptr = (TUint8*) aDir + (offsets[middleIndex] << 2);
sl@0
   119
			pCurrentEntry = (TRofsEntry*)  ptr;
sl@0
   120
sl@0
   121
			TPtrC currName=TPtrC((const TText*)&pCurrentEntry->iName[0],pCurrentEntry->iNameLength);
sl@0
   122
sl@0
   123
			TInt result=Compare(aName,currName);
sl@0
   124
			if(result<0)
sl@0
   125
				topIndex=middleIndex-1;
sl@0
   126
			else if(result>0)
sl@0
   127
				bottomIndex=middleIndex+1;
sl@0
   128
			else
sl@0
   129
				{
sl@0
   130
				bFound=ETrue;	// exit loop
sl@0
   131
				if (iMount.MatchEntryAtt(pCurrentEntry->iAtt, aAtt))
sl@0
   132
					{
sl@0
   133
					aSubDirEntry=pCurrentEntry;
sl@0
   134
					retVal=KErrNone;
sl@0
   135
					}
sl@0
   136
				}
sl@0
   137
			}
sl@0
   138
		}
sl@0
   139
	return retVal;
sl@0
   140
	}
sl@0
   141
sl@0
   142
TInt CDirectoryCache::DoFindSubDir(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aSubDirEntry ) const
sl@0
   143
	//
sl@0
   144
	// Scan the directory aDir looking for subdirectory aName. If aSubDirEntry is
sl@0
   145
	// not NULL the search starts from the entry AFTER aSubDirEntry.
sl@0
   146
	// If a matching entry is found writes pointer to the entry into aSubDirEntry
sl@0
   147
	// and returns KErrNone.
sl@0
   148
	//
sl@0
   149
	{
sl@0
   150
	const TRofsEntry* pEntry = aSubDirEntry;	// which entry
sl@0
   151
	const TRofsEntry* const pEnd = (TRofsEntry*)EndOfDirPlusOne( aDir );
sl@0
   152
sl@0
   153
	if( !pEntry )
sl@0
   154
		{
sl@0
   155
		pEntry = FirstSubDirEntryFromDir( aDir );
sl@0
   156
		}
sl@0
   157
	else
sl@0
   158
		{
sl@0
   159
		// move to next entry
sl@0
   160
		__ASSERT_DEBUG( pEntry >= FirstSubDirEntryFromDir( aDir ), CRofs::Panic( CRofs::EPanicEntryBeforeDirectory ));
sl@0
   161
		__ASSERT_DEBUG( pEntry < pEnd, CRofs::Panic( CRofs::EPanicEntryAfterDirectory ));
sl@0
   162
		pEntry = NextEntry( pEntry );
sl@0
   163
		}
sl@0
   164
sl@0
   165
	while ( pEntry < pEnd )
sl@0
   166
		{
sl@0
   167
		TPtrC name( NameAddress( pEntry ), pEntry->iNameLength);
sl@0
   168
		if ( KErrNotFound != name.MatchF(aName) && iMount.MatchEntryAtt(pEntry->iAtt, aAtt) )
sl@0
   169
			{
sl@0
   170
			aSubDirEntry = pEntry;
sl@0
   171
			return KErrNone;
sl@0
   172
			}
sl@0
   173
		
sl@0
   174
		pEntry = NextEntry( pEntry );
sl@0
   175
		}
sl@0
   176
	return KErrNotFound;
sl@0
   177
	}
sl@0
   178
sl@0
   179
TInt CDirectoryCache::GetDirCount(const TRofsDir* aDir) const
sl@0
   180
//
sl@0
   181
//Return the number of directory entries contained in aDir
sl@0
   182
//
sl@0
   183
	{
sl@0
   184
	TUint16* dirCount = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
sl@0
   185
	return *dirCount;
sl@0
   186
	}
sl@0
   187
sl@0
   188
TInt CDirectoryCache::GetFileCount(const TRofsDir* aDir) const
sl@0
   189
//
sl@0
   190
//Return the number of file entries contained in aDir
sl@0
   191
//
sl@0
   192
	{
sl@0
   193
	TUint16* fileCount = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
sl@0
   194
	fileCount++; //jump over the dir count
sl@0
   195
	return *fileCount;
sl@0
   196
	}
sl@0
   197
sl@0
   198
TInt CDirectoryCache::Compare(const TDesC& aLeft, const TDesC& aRight) const
sl@0
   199
//
sl@0
   200
//Compares two filenames.  Folds ASCII characters to uppercase
sl@0
   201
//
sl@0
   202
	{
sl@0
   203
sl@0
   204
	TInt len=Min(aLeft.Length(),aRight.Length());
sl@0
   205
	const TText* leftString = aLeft.Ptr();
sl@0
   206
	const TText* rightString = aRight.Ptr();
sl@0
   207
	while (len--)
sl@0
   208
		{
sl@0
   209
		TText leftChar=*leftString++;
sl@0
   210
		TText rightChar=*rightString++;
sl@0
   211
		if (leftChar<='Z' && leftChar>='A')
sl@0
   212
			leftChar +='a'-'A';     // covert to UPPERCASE
sl@0
   213
		if (rightChar<='Z' && rightChar>='A')
sl@0
   214
			rightChar +='a'-'A';    // covert to UPPERCASE
sl@0
   215
		TInt result=leftChar-rightChar;
sl@0
   216
		if (result != 0)
sl@0
   217
			return result;
sl@0
   218
		}
sl@0
   219
		// match up to end of shorter string, now compare lengths
sl@0
   220
		return aLeft.Length()-aRight.Length();
sl@0
   221
	}
sl@0
   222
sl@0
   223
TInt CDirectoryCache::ExtractMangleInfo(const TDesC& searchName, TUint8 &MountId, TUint8 &ReservedId) const
sl@0
   224
{
sl@0
   225
	#define HexToInt(x) ( x.IsDigit()? (TUint8)(x-(TUint)'0') : 0x0a+(TUint8)((x>='A' && x<='Z')? x-(TUint)'A':x-(TUint)'a') )
sl@0
   226
	const TInt KOpenBraceRevPos = 7;
sl@0
   227
	const TInt KHyphenRevPos = 4;
sl@0
   228
	const TInt KCloseBraceRevPos = 1;
sl@0
   229
sl@0
   230
	TInt openBraceRevPos = searchName.LocateReverse('[');
sl@0
   231
	TInt closeBraceRevPos = searchName.LocateReverse(']');
sl@0
   232
	TInt hyphenRevPos = searchName.LocateReverse('-');
sl@0
   233
	TInt searchNameLen = searchName.Length();
sl@0
   234
sl@0
   235
	if(openBraceRevPos==KErrNotFound || closeBraceRevPos==KErrNotFound || hyphenRevPos==KErrNotFound)
sl@0
   236
		return KErrNotFound;
sl@0
   237
sl@0
   238
	openBraceRevPos = searchNameLen - openBraceRevPos;
sl@0
   239
	closeBraceRevPos = searchNameLen - closeBraceRevPos;
sl@0
   240
	hyphenRevPos = searchNameLen - hyphenRevPos;
sl@0
   241
	if(openBraceRevPos!=KOpenBraceRevPos || hyphenRevPos!=KHyphenRevPos || closeBraceRevPos!=KCloseBraceRevPos)
sl@0
   242
		return KErrNotFound;
sl@0
   243
sl@0
   244
	const TText* nameString = searchName.Ptr();
sl@0
   245
	TInt MountIdPos = searchNameLen - KOpenBraceRevPos + 1;
sl@0
   246
	TInt ReservedIdPos = searchNameLen - KHyphenRevPos + 1;
sl@0
   247
sl@0
   248
	TChar MountIdHNibble = *(nameString+MountIdPos);
sl@0
   249
	TChar MountIdLNibble = *(nameString+MountIdPos+1);
sl@0
   250
sl@0
   251
	TChar ReservedIdHNibble = *(nameString+ReservedIdPos);
sl@0
   252
	TChar ReservedIdLNibble = *(nameString+ReservedIdPos+1);
sl@0
   253
sl@0
   254
	if(MountIdHNibble.IsHexDigit() && MountIdLNibble.IsHexDigit() &&
sl@0
   255
			ReservedIdHNibble.IsHexDigit() && ReservedIdLNibble.IsHexDigit())
sl@0
   256
	{
sl@0
   257
		MountId = (TUint8)((HexToInt(MountIdHNibble) << 4) | HexToInt(MountIdLNibble));
sl@0
   258
		ReservedId = (TUint8)((HexToInt(ReservedIdHNibble) << 4) | HexToInt(ReservedIdLNibble));
sl@0
   259
		return KErrNone;
sl@0
   260
	}
sl@0
   261
	return KErrNotFound;
sl@0
   262
}
sl@0
   263
sl@0
   264
TInt CDirectoryCache::DoBinaryFindFile(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aEntry ) const
sl@0
   265
//
sl@0
   266
// Scan from aDir looking for file aName using binary search.
sl@0
   267
// aName cannot contain wildcards and aEntry should always be NULL.
sl@0
   268
// If found return the result in aEntry.
sl@0
   269
//
sl@0
   270
	{
sl@0
   271
	if (aEntry != NULL)
sl@0
   272
		{
sl@0
   273
		return DoFindFile(aName, aAtt, aDir, aEntry);
sl@0
   274
		}
sl@0
   275
sl@0
   276
	TInt numFiles=GetFileCount(aDir);
sl@0
   277
	TInt topIndex=numFiles-1;
sl@0
   278
	TInt bottomIndex=0;
sl@0
   279
	TInt result;
sl@0
   280
	TBool doNameMangle = ETrue;
sl@0
   281
	TBuf<KMaxFileName> searchName;
sl@0
   282
sl@0
   283
	TBool bFound=EFalse;
sl@0
   284
	TInt retVal=KErrNotFound;
sl@0
   285
sl@0
   286
	searchName.Copy((const TText*)aName.Ptr(), aName.Length());
sl@0
   287
sl@0
   288
	if(topIndex>=0)
sl@0
   289
		{
sl@0
   290
		TUint16* offsets = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
sl@0
   291
		offsets += 2;                 //to skip file and dir counts
sl@0
   292
		offsets += GetDirCount(aDir); //skip directory offsets
sl@0
   293
sl@0
   294
		while((!bFound) && (topIndex>=bottomIndex))
sl@0
   295
			{
sl@0
   296
			TInt32 middleIndex;
sl@0
   297
			const TRofsEntry* pCurrentEntry=NULL;
sl@0
   298
			TBuf<KMaxFileName> currName;
sl@0
   299
sl@0
   300
			middleIndex=(topIndex+bottomIndex)>>1;
sl@0
   301
sl@0
   302
			//Offsets for files are relative to the start of the
sl@0
   303
			//file block
sl@0
   304
			TInt bufferOffset = (offsets[middleIndex]<<2) - iFilesMediaOffset + 4;
sl@0
   305
			bufferOffset += aDir->iFileBlockAddress;
sl@0
   306
sl@0
   307
			TUint8* ptr = (TUint8*) &iFilesBuffer[0];
sl@0
   308
sl@0
   309
			pCurrentEntry=(TRofsEntry*) &ptr[bufferOffset];
sl@0
   310
sl@0
   311
			currName.Copy(((const TText*)&pCurrentEntry->iName[0]), pCurrentEntry->iNameLength);
sl@0
   312
sl@0
   313
			if(doNameMangle && ((~pCurrentEntry->iAttExtra & (KEntryAttUnique >> 23)) != 0))
sl@0
   314
				currName.AppendFormat(_L("[%02x-00]"),iMount.iMountId);
sl@0
   315
sl@0
   316
			result=Compare(searchName,currName);
sl@0
   317
sl@0
   318
			if(result<0)
sl@0
   319
				topIndex=middleIndex-1;
sl@0
   320
			else if(result>0)
sl@0
   321
				bottomIndex=middleIndex+1;
sl@0
   322
			else
sl@0
   323
				{
sl@0
   324
				bFound=ETrue;	// exit loop
sl@0
   325
				if (iMount.MatchEntryAtt(pCurrentEntry->iAtt, aAtt))
sl@0
   326
					{
sl@0
   327
					aEntry=pCurrentEntry;
sl@0
   328
					retVal = (pCurrentEntry->iFileAddress == KFileHidden) ? KErrHidden : KErrNone;
sl@0
   329
					}
sl@0
   330
				/* If we have found a file and we are in second pass of binary search without nameMangle 
sl@0
   331
					check whether it is unique file */
sl@0
   332
				if(!doNameMangle)
sl@0
   333
					{
sl@0
   334
					/* If it is not a unique file then the file does not exist */
sl@0
   335
					if((~pCurrentEntry->iAttExtra & (KEntryAttUnique >> 23)) == 0)
sl@0
   336
						{
sl@0
   337
						retVal = KErrNotFound;
sl@0
   338
						aEntry = NULL;
sl@0
   339
						}
sl@0
   340
					}
sl@0
   341
				}
sl@0
   342
sl@0
   343
			/* If we are going to return and we are searching for the unique file,there is a possiblity
sl@0
   344
			   that the binary search would have missed it (since the file entries were sorted without 
sl@0
   345
			   namemangle).*/
sl@0
   346
			if((!bFound) && (topIndex<bottomIndex) && doNameMangle)
sl@0
   347
				{
sl@0
   348
					TUint8 MountId;
sl@0
   349
					TUint8 ReservedId;
sl@0
   350
sl@0
   351
					if(ExtractMangleInfo(searchName,MountId,ReservedId) != KErrNone)
sl@0
   352
						break;
sl@0
   353
sl@0
   354
					if(MountId != iMount.iMountId || ReservedId != 0)
sl@0
   355
						break;
sl@0
   356
sl@0
   357
					/* If the aNameLength is equal to the mangle name length, we cant proceed our search 
sl@0
   358
						with null strings */
sl@0
   359
					if((TUint)(aName.Length()) == KRofsMangleNameLength)
sl@0
   360
						break;
sl@0
   361
sl@0
   362
					searchName.Copy((const TText*)aName.Ptr(), aName.Length()-KRofsMangleNameLength);
sl@0
   363
sl@0
   364
					/* The next level of search is sufficient enough to start on the top portion of the list.
sl@0
   365
						Thus resetting the bottomIndex to 0 is sufficient */
sl@0
   366
					bottomIndex=0;
sl@0
   367
					doNameMangle = EFalse;
sl@0
   368
				}
sl@0
   369
			}
sl@0
   370
		}
sl@0
   371
	return retVal;
sl@0
   372
	}
sl@0
   373
sl@0
   374
TInt CDirectoryCache::DoFindFile(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aEntry ) const
sl@0
   375
//
sl@0
   376
// Scan from aDir looking for file aName.
sl@0
   377
// The search starts at the entry after aEntry, unless aEntry is NULL, in which
sl@0
   378
// case the srach starts from the beginning of the file block.
sl@0
   379
// If found return the result in aEntry.
sl@0
   380
//
sl@0
   381
	{
sl@0
   382
	__ASSERT_DEBUG( aDir != NULL, CRofs::Panic( CRofs::EPanicNullSubDir ));
sl@0
   383
	
sl@0
   384
	if( aDir->iFileBlockAddress )
sl@0
   385
		{
sl@0
   386
		const TRofsEntry* pEntry;
sl@0
   387
		if( !aEntry )
sl@0
   388
			{
sl@0
   389
			pEntry = FirstFileEntryFromDir( aDir );
sl@0
   390
			}
sl@0
   391
		else
sl@0
   392
			{
sl@0
   393
			pEntry = NextEntry( aEntry );
sl@0
   394
			}
sl@0
   395
		const TAny* const pEnd = EndOfFileBlockPlusOne( aDir );
sl@0
   396
		
sl@0
   397
		while ( pEntry < pEnd )
sl@0
   398
			{
sl@0
   399
			TBuf<KMaxFileName> fileName;
sl@0
   400
sl@0
   401
			fileName.Copy(NameAddress( pEntry ), pEntry->iNameLength);
sl@0
   402
			if((~pEntry->iAttExtra & (KEntryAttUnique >> 23)) != 0)
sl@0
   403
				fileName.AppendFormat(_L("[%02x-00]"),iMount.iMountId);
sl@0
   404
sl@0
   405
			if ( KErrNotFound != fileName.MatchF(aName) && iMount.MatchEntryAtt(pEntry->iAtt, aAtt)  )
sl@0
   406
				{
sl@0
   407
				aEntry = pEntry;
sl@0
   408
				return(( pEntry->iFileAddress == KFileHidden ) ? KErrHidden : KErrNone);
sl@0
   409
				}
sl@0
   410
			
sl@0
   411
			pEntry = NextEntry( pEntry );
sl@0
   412
			}
sl@0
   413
		}
sl@0
   414
	return KErrNotFound;
sl@0
   415
	}
sl@0
   416
sl@0
   417
sl@0
   418
void CDirectoryCache::FindFileEntryL(const TDesC& aName, const TRofsEntry*& aEntry) const
sl@0
   419
//
sl@0
   420
// Locate an entry from its full path name.
sl@0
   421
//
sl@0
   422
	{
sl@0
   423
	TInt namePos=aName.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
sl@0
   424
	const TRofsDir* dir = RootDirectory();
sl@0
   425
	FindLeafDirL(aName.Left(namePos), dir);
sl@0
   426
sl@0
   427
	aEntry=0;
sl@0
   428
	TInt r = DoBinaryFindFile(aName.Mid(namePos), KEntryAttDir|KEntryAttMatchExclude, dir, aEntry);
sl@0
   429
	if (r!=KErrNone)
sl@0
   430
		User::Leave(r);
sl@0
   431
	}
sl@0
   432
sl@0
   433
void CDirectoryCache::FindDirectoryEntryL(const TDesC& aName, const TRofsDir*& aDir) const
sl@0
   434
//
sl@0
   435
// Locate an entry from its full path name.
sl@0
   436
//
sl@0
   437
	{
sl@0
   438
	aDir = RootDirectory();
sl@0
   439
	FindLeafDirL(aName,aDir);
sl@0
   440
	}
sl@0
   441
sl@0
   442
sl@0
   443
void CDirectoryCache::GetNextMatchingL(const TDesC& aName, TUint aAtt, const TRofsDir*& aDir, const TRofsEntry*& aEntry, TInt aError, TBool bUseBinarySearch) const
sl@0
   444
	//
sl@0
   445
	// Retrieves the next directory or file entry from aDir that matches the pattern in aName
sl@0
   446
	// (which should be the entry name only, not the full path)
sl@0
   447
	// The search starts at the entry after aEntry
sl@0
   448
	//
sl@0
   449
	{
sl@0
   450
	__ASSERT_DEBUG( aName.LocateReverse(KPathDelimiter) == KErrNotFound, CRofs::Panic( CRofs::EPanicBadMatchName ));
sl@0
   451
sl@0
   452
	TInt r = KErrGeneral;
sl@0
   453
	const TRofsEntry* entry = aEntry;
sl@0
   454
	TBool searchFiles = EFalse;
sl@0
   455
	if( entry && (entry < FirstSubDirEntryFromDir(aDir) || entry >= EndOfDirPlusOne(aDir)) )
sl@0
   456
		{
sl@0
   457
		searchFiles = ETrue;
sl@0
   458
		}
sl@0
   459
	else
sl@0
   460
		{
sl@0
   461
		// searching the directory list
sl@0
   462
		if (!bUseBinarySearch)
sl@0
   463
			{
sl@0
   464
			r = DoFindSubDir( aName, aAtt, aDir, entry );
sl@0
   465
			}
sl@0
   466
		else
sl@0
   467
			{
sl@0
   468
			r = DoBinaryFindSubDir(aName, aAtt, aDir, entry);
sl@0
   469
			}
sl@0
   470
		if( KErrNotFound == r )
sl@0
   471
			{
sl@0
   472
			// start looking through the file list
sl@0
   473
			entry = NULL;	// start at beginning of list
sl@0
   474
			searchFiles = ETrue;
sl@0
   475
			}
sl@0
   476
		}
sl@0
   477
sl@0
   478
sl@0
   479
	if( searchFiles )
sl@0
   480
		{
sl@0
   481
		if (!bUseBinarySearch)
sl@0
   482
			{
sl@0
   483
			r = DoFindFile( aName, aAtt, aDir, entry );
sl@0
   484
			}
sl@0
   485
		else
sl@0
   486
			{
sl@0
   487
			r = DoBinaryFindFile(aName, aAtt, aDir, entry);
sl@0
   488
			}
sl@0
   489
		}
sl@0
   490
sl@0
   491
/*
sl@0
   492
	if( aEntry >= FirstFileEntryFromDir( aDir ) 
sl@0
   493
		&& aDir->iFileBlockAddress )
sl@0
   494
		{
sl@0
   495
		// we are searching the file list
sl@0
   496
		r = DoFindFile( aName, aAtt, aDir, aEntry );
sl@0
   497
		}
sl@0
   498
	else
sl@0
   499
		{
sl@0
   500
		// searching the directory list
sl@0
   501
		r = DoFindSubDir( aName, aAtt, aDir, aEntry );
sl@0
   502
		if( KErrNotFound == r )
sl@0
   503
			{
sl@0
   504
			// start looking through the file list
sl@0
   505
			TRofsEntry* entry = NULL;	// start at beginning of list
sl@0
   506
			r = DoFindFile( aName, aAtt, aDir, entry );
sl@0
   507
			if( KErrNone == r )
sl@0
   508
				{
sl@0
   509
				aEntry = entry;
sl@0
   510
				}
sl@0
   511
			}
sl@0
   512
		}
sl@0
   513
*/
sl@0
   514
sl@0
   515
	if( r == KErrNone || r == KErrHidden)
sl@0
   516
		{
sl@0
   517
		// Move onto the next entry (this is valid even for hidden entries so
sl@0
   518
		// that we can move onto the next entry, which may not be hidden)
sl@0
   519
		aEntry = entry;
sl@0
   520
		if(r == KErrNone)
sl@0
   521
			{
sl@0
   522
			return;
sl@0
   523
			}
sl@0
   524
		}
sl@0
   525
sl@0
   526
	User::Leave(r == KErrHidden ? r : aError);
sl@0
   527
	}
sl@0
   528
sl@0
   529
void CDirectoryCache::FindGeneralEntryL(const TDesC& aName, TUint aAtt, const TRofsDir*& aDir, const TRofsEntry*& aEntry ) const
sl@0
   530
	{
sl@0
   531
	TInt namePos=aName.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
sl@0
   532
	aDir = RootDirectory();
sl@0
   533
	FindLeafDirL(aName.Left(namePos), aDir);
sl@0
   534
	GetNextMatchingL( aName.Mid(namePos), aAtt, aDir, aEntry, KErrNotFound, ETrue );
sl@0
   535
	}
sl@0
   536
sl@0
   537
TUint8 CDirectoryCache::GetMountId( void )
sl@0
   538
	{
sl@0
   539
	return (TUint8)(iMount.iMountId);
sl@0
   540
	};