1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/srofs/dircache.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,540 @@
1.4 +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32std.h>
1.20 +#include <e32std_private.h>
1.21 +#include "sr_rofs.h"
1.22 +#include <rofs.h>
1.23 +
1.24 +
1.25 +CDirectoryCache::CDirectoryCache( CRofsMountCB& aMount, CProxyDrive& aLocalDrive, const TRofsHeader& aHeader )
1.26 + : iMount( aMount ), iLocalDrive( aLocalDrive ),
1.27 + iTreeMediaOffset( aHeader.iDirTreeOffset ),
1.28 + iTreeSize( aHeader.iDirTreeSize ),
1.29 + iFilesMediaOffset( aHeader.iDirFileEntriesOffset ),
1.30 + iFilesSize( aHeader.iDirFileEntriesSize )
1.31 + {
1.32 + }
1.33 +
1.34 +CDirectoryCache::~CDirectoryCache()
1.35 + {
1.36 + delete iTreeBuffer;
1.37 + delete iFilesBuffer;
1.38 + }
1.39 +
1.40 +void CDirectoryCache::ConstructL()
1.41 + {
1.42 + iTreeBuffer = HBufC8::NewL( iTreeSize );
1.43 + iFilesBuffer = HBufC8::NewL( iFilesSize );
1.44 +
1.45 + TPtr8 ptr = iTreeBuffer->Des();
1.46 + User::LeaveIfError( iLocalDrive.Read( iTreeMediaOffset, iTreeSize, ptr) );
1.47 + TPtr8 ptr2 = iFilesBuffer->Des();
1.48 + User::LeaveIfError( iLocalDrive.Read( iFilesMediaOffset, iFilesSize, ptr2) );
1.49 + }
1.50 +
1.51 +
1.52 +void CDirectoryCache::FindLeafDirL(const TDesC& aName, const TRofsDir*& aDir) const
1.53 +//
1.54 +// Navigate the path to find the leaf directory, starting at aDir.
1.55 +//
1.56 + {
1.57 +
1.58 + TLex lex(aName);
1.59 + TInt r;
1.60 + FOREVER
1.61 + {
1.62 + lex.Inc(); // Skip the file separator
1.63 + lex.Mark();
1.64 + r=lex.Remainder().Locate(KPathDelimiter);
1.65 +
1.66 + if ( KErrNotFound == r )
1.67 + {
1.68 + r=lex.Remainder().Length();
1.69 + }
1.70 + if ( 0 == r ) // End of the path
1.71 + {
1.72 + break;
1.73 + }
1.74 +
1.75 + lex.Inc(r); // Set the token length
1.76 +
1.77 + const TRofsEntry* subDirEntry = NULL;
1.78 + TInt r = DoBinaryFindSubDir(lex.MarkedToken(), KEntryAttDir|KEntryAttMatchExclusive, aDir, subDirEntry );
1.79 + if( KErrNone != r )
1.80 + {
1.81 + User::Leave( KErrPathNotFound );
1.82 + }
1.83 + __ASSERT_DEBUG( 0 != (subDirEntry->iAtt & KEntryAttDir ), CRofs::Panic( CRofs::EPanicEntryNotDir ));
1.84 + aDir = RofsDirFromSubDirEntry( subDirEntry );
1.85 + }
1.86 + }
1.87 +
1.88 +TInt CDirectoryCache::DoBinaryFindSubDir(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aSubDirEntry ) const
1.89 + //
1.90 + // Scan the directory aDir looking for subdirectory aName using binary search.
1.91 + // aName cannot contain wildcards and aSubDirEntry should always be NULL.
1.92 + // If a matching entry is found writes pointer to the entry into aSubDirEntry
1.93 + // and returns KErrNone.
1.94 + //
1.95 + {
1.96 +
1.97 + if (aSubDirEntry != NULL)
1.98 + {
1.99 + return DoFindSubDir(aName, aAtt, aDir, aSubDirEntry);
1.100 + }
1.101 +
1.102 + TInt numDirs=GetDirCount(aDir);
1.103 + TInt topIndex=numDirs-1;
1.104 + TInt bottomIndex=0;
1.105 +
1.106 + TBool bFound=EFalse;
1.107 + TInt retVal=KErrNotFound;
1.108 + if(topIndex>=0)
1.109 + {
1.110 + TUint16* offsets = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
1.111 + offsets += 2; //to skip file and dir counts
1.112 +
1.113 + while((!bFound) && (topIndex>=bottomIndex))
1.114 + {
1.115 + TInt32 middleIndex;
1.116 + const TRofsEntry* pCurrentEntry=NULL;
1.117 + middleIndex=(topIndex+bottomIndex)>>1;
1.118 +
1.119 + //Offsets for directories are relative to the start of the
1.120 + //directory block
1.121 + TUint8* ptr = (TUint8*) aDir + (offsets[middleIndex] << 2);
1.122 + pCurrentEntry = (TRofsEntry*) ptr;
1.123 +
1.124 + TPtrC currName=TPtrC((const TText*)&pCurrentEntry->iName[0],pCurrentEntry->iNameLength);
1.125 +
1.126 + TInt result=Compare(aName,currName);
1.127 + if(result<0)
1.128 + topIndex=middleIndex-1;
1.129 + else if(result>0)
1.130 + bottomIndex=middleIndex+1;
1.131 + else
1.132 + {
1.133 + bFound=ETrue; // exit loop
1.134 + if (iMount.MatchEntryAtt(pCurrentEntry->iAtt, aAtt))
1.135 + {
1.136 + aSubDirEntry=pCurrentEntry;
1.137 + retVal=KErrNone;
1.138 + }
1.139 + }
1.140 + }
1.141 + }
1.142 + return retVal;
1.143 + }
1.144 +
1.145 +TInt CDirectoryCache::DoFindSubDir(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aSubDirEntry ) const
1.146 + //
1.147 + // Scan the directory aDir looking for subdirectory aName. If aSubDirEntry is
1.148 + // not NULL the search starts from the entry AFTER aSubDirEntry.
1.149 + // If a matching entry is found writes pointer to the entry into aSubDirEntry
1.150 + // and returns KErrNone.
1.151 + //
1.152 + {
1.153 + const TRofsEntry* pEntry = aSubDirEntry; // which entry
1.154 + const TRofsEntry* const pEnd = (TRofsEntry*)EndOfDirPlusOne( aDir );
1.155 +
1.156 + if( !pEntry )
1.157 + {
1.158 + pEntry = FirstSubDirEntryFromDir( aDir );
1.159 + }
1.160 + else
1.161 + {
1.162 + // move to next entry
1.163 + __ASSERT_DEBUG( pEntry >= FirstSubDirEntryFromDir( aDir ), CRofs::Panic( CRofs::EPanicEntryBeforeDirectory ));
1.164 + __ASSERT_DEBUG( pEntry < pEnd, CRofs::Panic( CRofs::EPanicEntryAfterDirectory ));
1.165 + pEntry = NextEntry( pEntry );
1.166 + }
1.167 +
1.168 + while ( pEntry < pEnd )
1.169 + {
1.170 + TPtrC name( NameAddress( pEntry ), pEntry->iNameLength);
1.171 + if ( KErrNotFound != name.MatchF(aName) && iMount.MatchEntryAtt(pEntry->iAtt, aAtt) )
1.172 + {
1.173 + aSubDirEntry = pEntry;
1.174 + return KErrNone;
1.175 + }
1.176 +
1.177 + pEntry = NextEntry( pEntry );
1.178 + }
1.179 + return KErrNotFound;
1.180 + }
1.181 +
1.182 +TInt CDirectoryCache::GetDirCount(const TRofsDir* aDir) const
1.183 +//
1.184 +//Return the number of directory entries contained in aDir
1.185 +//
1.186 + {
1.187 + TUint16* dirCount = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
1.188 + return *dirCount;
1.189 + }
1.190 +
1.191 +TInt CDirectoryCache::GetFileCount(const TRofsDir* aDir) const
1.192 +//
1.193 +//Return the number of file entries contained in aDir
1.194 +//
1.195 + {
1.196 + TUint16* fileCount = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
1.197 + fileCount++; //jump over the dir count
1.198 + return *fileCount;
1.199 + }
1.200 +
1.201 +TInt CDirectoryCache::Compare(const TDesC& aLeft, const TDesC& aRight) const
1.202 +//
1.203 +//Compares two filenames. Folds ASCII characters to uppercase
1.204 +//
1.205 + {
1.206 +
1.207 + TInt len=Min(aLeft.Length(),aRight.Length());
1.208 + const TText* leftString = aLeft.Ptr();
1.209 + const TText* rightString = aRight.Ptr();
1.210 + while (len--)
1.211 + {
1.212 + TText leftChar=*leftString++;
1.213 + TText rightChar=*rightString++;
1.214 + if (leftChar<='Z' && leftChar>='A')
1.215 + leftChar +='a'-'A'; // covert to UPPERCASE
1.216 + if (rightChar<='Z' && rightChar>='A')
1.217 + rightChar +='a'-'A'; // covert to UPPERCASE
1.218 + TInt result=leftChar-rightChar;
1.219 + if (result != 0)
1.220 + return result;
1.221 + }
1.222 + // match up to end of shorter string, now compare lengths
1.223 + return aLeft.Length()-aRight.Length();
1.224 + }
1.225 +
1.226 +TInt CDirectoryCache::ExtractMangleInfo(const TDesC& searchName, TUint8 &MountId, TUint8 &ReservedId) const
1.227 +{
1.228 + #define HexToInt(x) ( x.IsDigit()? (TUint8)(x-(TUint)'0') : 0x0a+(TUint8)((x>='A' && x<='Z')? x-(TUint)'A':x-(TUint)'a') )
1.229 + const TInt KOpenBraceRevPos = 7;
1.230 + const TInt KHyphenRevPos = 4;
1.231 + const TInt KCloseBraceRevPos = 1;
1.232 +
1.233 + TInt openBraceRevPos = searchName.LocateReverse('[');
1.234 + TInt closeBraceRevPos = searchName.LocateReverse(']');
1.235 + TInt hyphenRevPos = searchName.LocateReverse('-');
1.236 + TInt searchNameLen = searchName.Length();
1.237 +
1.238 + if(openBraceRevPos==KErrNotFound || closeBraceRevPos==KErrNotFound || hyphenRevPos==KErrNotFound)
1.239 + return KErrNotFound;
1.240 +
1.241 + openBraceRevPos = searchNameLen - openBraceRevPos;
1.242 + closeBraceRevPos = searchNameLen - closeBraceRevPos;
1.243 + hyphenRevPos = searchNameLen - hyphenRevPos;
1.244 + if(openBraceRevPos!=KOpenBraceRevPos || hyphenRevPos!=KHyphenRevPos || closeBraceRevPos!=KCloseBraceRevPos)
1.245 + return KErrNotFound;
1.246 +
1.247 + const TText* nameString = searchName.Ptr();
1.248 + TInt MountIdPos = searchNameLen - KOpenBraceRevPos + 1;
1.249 + TInt ReservedIdPos = searchNameLen - KHyphenRevPos + 1;
1.250 +
1.251 + TChar MountIdHNibble = *(nameString+MountIdPos);
1.252 + TChar MountIdLNibble = *(nameString+MountIdPos+1);
1.253 +
1.254 + TChar ReservedIdHNibble = *(nameString+ReservedIdPos);
1.255 + TChar ReservedIdLNibble = *(nameString+ReservedIdPos+1);
1.256 +
1.257 + if(MountIdHNibble.IsHexDigit() && MountIdLNibble.IsHexDigit() &&
1.258 + ReservedIdHNibble.IsHexDigit() && ReservedIdLNibble.IsHexDigit())
1.259 + {
1.260 + MountId = (TUint8)((HexToInt(MountIdHNibble) << 4) | HexToInt(MountIdLNibble));
1.261 + ReservedId = (TUint8)((HexToInt(ReservedIdHNibble) << 4) | HexToInt(ReservedIdLNibble));
1.262 + return KErrNone;
1.263 + }
1.264 + return KErrNotFound;
1.265 +}
1.266 +
1.267 +TInt CDirectoryCache::DoBinaryFindFile(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aEntry ) const
1.268 +//
1.269 +// Scan from aDir looking for file aName using binary search.
1.270 +// aName cannot contain wildcards and aEntry should always be NULL.
1.271 +// If found return the result in aEntry.
1.272 +//
1.273 + {
1.274 + if (aEntry != NULL)
1.275 + {
1.276 + return DoFindFile(aName, aAtt, aDir, aEntry);
1.277 + }
1.278 +
1.279 + TInt numFiles=GetFileCount(aDir);
1.280 + TInt topIndex=numFiles-1;
1.281 + TInt bottomIndex=0;
1.282 + TInt result;
1.283 + TBool doNameMangle = ETrue;
1.284 + TBuf<KMaxFileName> searchName;
1.285 +
1.286 + TBool bFound=EFalse;
1.287 + TInt retVal=KErrNotFound;
1.288 +
1.289 + searchName.Copy((const TText*)aName.Ptr(), aName.Length());
1.290 +
1.291 + if(topIndex>=0)
1.292 + {
1.293 + TUint16* offsets = (TUint16*) ((TUint8*) aDir + aDir->iStructSize);
1.294 + offsets += 2; //to skip file and dir counts
1.295 + offsets += GetDirCount(aDir); //skip directory offsets
1.296 +
1.297 + while((!bFound) && (topIndex>=bottomIndex))
1.298 + {
1.299 + TInt32 middleIndex;
1.300 + const TRofsEntry* pCurrentEntry=NULL;
1.301 + TBuf<KMaxFileName> currName;
1.302 +
1.303 + middleIndex=(topIndex+bottomIndex)>>1;
1.304 +
1.305 + //Offsets for files are relative to the start of the
1.306 + //file block
1.307 + TInt bufferOffset = (offsets[middleIndex]<<2) - iFilesMediaOffset + 4;
1.308 + bufferOffset += aDir->iFileBlockAddress;
1.309 +
1.310 + TUint8* ptr = (TUint8*) &iFilesBuffer[0];
1.311 +
1.312 + pCurrentEntry=(TRofsEntry*) &ptr[bufferOffset];
1.313 +
1.314 + currName.Copy(((const TText*)&pCurrentEntry->iName[0]), pCurrentEntry->iNameLength);
1.315 +
1.316 + if(doNameMangle && ((~pCurrentEntry->iAttExtra & (KEntryAttUnique >> 23)) != 0))
1.317 + currName.AppendFormat(_L("[%02x-00]"),iMount.iMountId);
1.318 +
1.319 + result=Compare(searchName,currName);
1.320 +
1.321 + if(result<0)
1.322 + topIndex=middleIndex-1;
1.323 + else if(result>0)
1.324 + bottomIndex=middleIndex+1;
1.325 + else
1.326 + {
1.327 + bFound=ETrue; // exit loop
1.328 + if (iMount.MatchEntryAtt(pCurrentEntry->iAtt, aAtt))
1.329 + {
1.330 + aEntry=pCurrentEntry;
1.331 + retVal = (pCurrentEntry->iFileAddress == KFileHidden) ? KErrHidden : KErrNone;
1.332 + }
1.333 + /* If we have found a file and we are in second pass of binary search without nameMangle
1.334 + check whether it is unique file */
1.335 + if(!doNameMangle)
1.336 + {
1.337 + /* If it is not a unique file then the file does not exist */
1.338 + if((~pCurrentEntry->iAttExtra & (KEntryAttUnique >> 23)) == 0)
1.339 + {
1.340 + retVal = KErrNotFound;
1.341 + aEntry = NULL;
1.342 + }
1.343 + }
1.344 + }
1.345 +
1.346 + /* If we are going to return and we are searching for the unique file,there is a possiblity
1.347 + that the binary search would have missed it (since the file entries were sorted without
1.348 + namemangle).*/
1.349 + if((!bFound) && (topIndex<bottomIndex) && doNameMangle)
1.350 + {
1.351 + TUint8 MountId;
1.352 + TUint8 ReservedId;
1.353 +
1.354 + if(ExtractMangleInfo(searchName,MountId,ReservedId) != KErrNone)
1.355 + break;
1.356 +
1.357 + if(MountId != iMount.iMountId || ReservedId != 0)
1.358 + break;
1.359 +
1.360 + /* If the aNameLength is equal to the mangle name length, we cant proceed our search
1.361 + with null strings */
1.362 + if((TUint)(aName.Length()) == KRofsMangleNameLength)
1.363 + break;
1.364 +
1.365 + searchName.Copy((const TText*)aName.Ptr(), aName.Length()-KRofsMangleNameLength);
1.366 +
1.367 + /* The next level of search is sufficient enough to start on the top portion of the list.
1.368 + Thus resetting the bottomIndex to 0 is sufficient */
1.369 + bottomIndex=0;
1.370 + doNameMangle = EFalse;
1.371 + }
1.372 + }
1.373 + }
1.374 + return retVal;
1.375 + }
1.376 +
1.377 +TInt CDirectoryCache::DoFindFile(const TDesC& aName, TUint aAtt, const TRofsDir* aDir, const TRofsEntry*& aEntry ) const
1.378 +//
1.379 +// Scan from aDir looking for file aName.
1.380 +// The search starts at the entry after aEntry, unless aEntry is NULL, in which
1.381 +// case the srach starts from the beginning of the file block.
1.382 +// If found return the result in aEntry.
1.383 +//
1.384 + {
1.385 + __ASSERT_DEBUG( aDir != NULL, CRofs::Panic( CRofs::EPanicNullSubDir ));
1.386 +
1.387 + if( aDir->iFileBlockAddress )
1.388 + {
1.389 + const TRofsEntry* pEntry;
1.390 + if( !aEntry )
1.391 + {
1.392 + pEntry = FirstFileEntryFromDir( aDir );
1.393 + }
1.394 + else
1.395 + {
1.396 + pEntry = NextEntry( aEntry );
1.397 + }
1.398 + const TAny* const pEnd = EndOfFileBlockPlusOne( aDir );
1.399 +
1.400 + while ( pEntry < pEnd )
1.401 + {
1.402 + TBuf<KMaxFileName> fileName;
1.403 +
1.404 + fileName.Copy(NameAddress( pEntry ), pEntry->iNameLength);
1.405 + if((~pEntry->iAttExtra & (KEntryAttUnique >> 23)) != 0)
1.406 + fileName.AppendFormat(_L("[%02x-00]"),iMount.iMountId);
1.407 +
1.408 + if ( KErrNotFound != fileName.MatchF(aName) && iMount.MatchEntryAtt(pEntry->iAtt, aAtt) )
1.409 + {
1.410 + aEntry = pEntry;
1.411 + return(( pEntry->iFileAddress == KFileHidden ) ? KErrHidden : KErrNone);
1.412 + }
1.413 +
1.414 + pEntry = NextEntry( pEntry );
1.415 + }
1.416 + }
1.417 + return KErrNotFound;
1.418 + }
1.419 +
1.420 +
1.421 +void CDirectoryCache::FindFileEntryL(const TDesC& aName, const TRofsEntry*& aEntry) const
1.422 +//
1.423 +// Locate an entry from its full path name.
1.424 +//
1.425 + {
1.426 + TInt namePos=aName.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
1.427 + const TRofsDir* dir = RootDirectory();
1.428 + FindLeafDirL(aName.Left(namePos), dir);
1.429 +
1.430 + aEntry=0;
1.431 + TInt r = DoBinaryFindFile(aName.Mid(namePos), KEntryAttDir|KEntryAttMatchExclude, dir, aEntry);
1.432 + if (r!=KErrNone)
1.433 + User::Leave(r);
1.434 + }
1.435 +
1.436 +void CDirectoryCache::FindDirectoryEntryL(const TDesC& aName, const TRofsDir*& aDir) const
1.437 +//
1.438 +// Locate an entry from its full path name.
1.439 +//
1.440 + {
1.441 + aDir = RootDirectory();
1.442 + FindLeafDirL(aName,aDir);
1.443 + }
1.444 +
1.445 +
1.446 +void CDirectoryCache::GetNextMatchingL(const TDesC& aName, TUint aAtt, const TRofsDir*& aDir, const TRofsEntry*& aEntry, TInt aError, TBool bUseBinarySearch) const
1.447 + //
1.448 + // Retrieves the next directory or file entry from aDir that matches the pattern in aName
1.449 + // (which should be the entry name only, not the full path)
1.450 + // The search starts at the entry after aEntry
1.451 + //
1.452 + {
1.453 + __ASSERT_DEBUG( aName.LocateReverse(KPathDelimiter) == KErrNotFound, CRofs::Panic( CRofs::EPanicBadMatchName ));
1.454 +
1.455 + TInt r = KErrGeneral;
1.456 + const TRofsEntry* entry = aEntry;
1.457 + TBool searchFiles = EFalse;
1.458 + if( entry && (entry < FirstSubDirEntryFromDir(aDir) || entry >= EndOfDirPlusOne(aDir)) )
1.459 + {
1.460 + searchFiles = ETrue;
1.461 + }
1.462 + else
1.463 + {
1.464 + // searching the directory list
1.465 + if (!bUseBinarySearch)
1.466 + {
1.467 + r = DoFindSubDir( aName, aAtt, aDir, entry );
1.468 + }
1.469 + else
1.470 + {
1.471 + r = DoBinaryFindSubDir(aName, aAtt, aDir, entry);
1.472 + }
1.473 + if( KErrNotFound == r )
1.474 + {
1.475 + // start looking through the file list
1.476 + entry = NULL; // start at beginning of list
1.477 + searchFiles = ETrue;
1.478 + }
1.479 + }
1.480 +
1.481 +
1.482 + if( searchFiles )
1.483 + {
1.484 + if (!bUseBinarySearch)
1.485 + {
1.486 + r = DoFindFile( aName, aAtt, aDir, entry );
1.487 + }
1.488 + else
1.489 + {
1.490 + r = DoBinaryFindFile(aName, aAtt, aDir, entry);
1.491 + }
1.492 + }
1.493 +
1.494 +/*
1.495 + if( aEntry >= FirstFileEntryFromDir( aDir )
1.496 + && aDir->iFileBlockAddress )
1.497 + {
1.498 + // we are searching the file list
1.499 + r = DoFindFile( aName, aAtt, aDir, aEntry );
1.500 + }
1.501 + else
1.502 + {
1.503 + // searching the directory list
1.504 + r = DoFindSubDir( aName, aAtt, aDir, aEntry );
1.505 + if( KErrNotFound == r )
1.506 + {
1.507 + // start looking through the file list
1.508 + TRofsEntry* entry = NULL; // start at beginning of list
1.509 + r = DoFindFile( aName, aAtt, aDir, entry );
1.510 + if( KErrNone == r )
1.511 + {
1.512 + aEntry = entry;
1.513 + }
1.514 + }
1.515 + }
1.516 +*/
1.517 +
1.518 + if( r == KErrNone || r == KErrHidden)
1.519 + {
1.520 + // Move onto the next entry (this is valid even for hidden entries so
1.521 + // that we can move onto the next entry, which may not be hidden)
1.522 + aEntry = entry;
1.523 + if(r == KErrNone)
1.524 + {
1.525 + return;
1.526 + }
1.527 + }
1.528 +
1.529 + User::Leave(r == KErrHidden ? r : aError);
1.530 + }
1.531 +
1.532 +void CDirectoryCache::FindGeneralEntryL(const TDesC& aName, TUint aAtt, const TRofsDir*& aDir, const TRofsEntry*& aEntry ) const
1.533 + {
1.534 + TInt namePos=aName.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
1.535 + aDir = RootDirectory();
1.536 + FindLeafDirL(aName.Left(namePos), aDir);
1.537 + GetNextMatchingL( aName.Mid(namePos), aAtt, aDir, aEntry, KErrNotFound, ETrue );
1.538 + }
1.539 +
1.540 +TUint8 CDirectoryCache::GetMountId( void )
1.541 + {
1.542 + return (TUint8)(iMount.iMountId);
1.543 + };