diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/sfsrv/cl_find.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfsrv/cl_find.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,674 @@ +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// f32\sfsrv\cl_find.cpp +// +// + +#include "cl_std.h" + +#define gPathDelimiter TChar(';') +enum TMode {EFindByDrives,EFindByDrivesInPath,EFindByPath}; + +TInt TFindFile::DoFindInDir() +// +// Look for aFileName in aDir +// + { + + if (iDir==NULL) + { + TEntry entry; + TInt r=iFs->Entry(iFile.FullName(),entry); + if (r==KErrNone /*|| r==KErrAccessDenied*/) + return(KErrNone); + else if (r==KErrNoMemory) + return r; + else if (r==KErrPermissionDenied) + return (KErrPermissionDenied); + else + return(KErrNotFound); + } + TInt r=iFs->GetDir(iFile.FullName(),KEntryAttMaskSupported|KEntryAttAllowUid,ESortByName,*iDir); + if (r==KErrNoMemory) + return r; + else if (r==KErrPermissionDenied) + return r; + else if (r!=KErrNone) + return(KErrNotFound); + if ((*iDir)->Count()==0) + { + delete (*iDir); + *iDir=NULL; + return(KErrNotFound); + } + else + return(KErrNone); + } + +TInt TFindFile::DoFindNextInPath() +// +// Look for aFileName along the path and increment aPathPos +// + { + + if (iMode==EFindByDrivesInPath) + { + TInt r=DoFindNextInDriveList(); + if (r==KErrNone) + return(KErrNone); + if (r!=KErrNotFound) + return(r); + iMode=EFindByPath; + } + FOREVER + { + if (iPath->Length()Ptr()+iPathPos,iPath->Length()-iPathPos); + TInt r=path.Locate(gPathDelimiter); + if (r==KErrNotFound) + r=path.Length(); + path.Set(path.Ptr(),r); + iPathPos+=r+1; + TFileName fileName=iFile.NameAndExt(); + iFile.Set(fileName,&path,NULL); + if (iFile.FullName().Length()>=2 && iFile.FullName()[1]==KDriveDelimiter) + { + TInt r=DoFindInDir(); + if (r==KErrNone) + return(KErrNone); + if (r!=KErrNotFound) + return(r); + continue; + } + iMode=EFindByDrivesInPath; + + r=FindByDir(fileName,path); + if (r==KErrNone) + return(KErrNone); + if (r!=KErrNotFound) + return(r); + } + + } + +TInt TFindFile::DoFindNextInDriveList() +// +// Look for aFileName in all available drives in order +// + { + + TInt found; + TDriveInfo driveInfo; + const TUint matchedFlags= iMatchMask & KDriveAttMatchedFlags; //KDriveAttMatchedFlags = 0xFFF + const TUint matchedAtt = iMatchMask & KDriveAttMatchedAtt; //KDriveAttMatchedAtt = 0x0FFF0000 + + if (iMatchMask == (KDriveAttExclude | KDriveAttMatchedFlags ) ) //If all drives are excluded. + return KErrNotFound; + + FOREVER + { + + found =0; + TInt currentDrive=iCurrentDrive; + + + if (iCurrentDrive==-1) + currentDrive=EDriveZ; + + + if (currentDrive<=-2) + return(KErrNotFound); + + + iCurrentDrive--; + + if (!iDrvList[currentDrive]) + continue; + + TInt err = iFs->Drive(driveInfo,currentDrive); + + if(iMatchMask == 0) + { + if (iDrvList[currentDrive] & KDriveAttRemote) + continue; // NOT allowed on REMOTE DRIVE + if ((iDrvList[currentDrive] & (KDriveAttLocal|KDriveAttRom))==0) + continue; + } + else + { + + if(matchedFlags != 0 ) + { + + switch(matchedAtt) + { //found ==0 means that this drive attributes didn't match the flags + + case KDriveAttExclude : + found = (driveInfo.iDriveAtt & matchedFlags ) ? 0:iDrvList[currentDrive] ; + break; + + case 0: + found = (driveInfo.iDriveAtt & matchedFlags) ? iDrvList[currentDrive]:0 ; + break; + + + case KDriveAttExclusive : + if(matchedFlags != KDriveAttLogicallyRemovable) + { + + found = ((TUint8)(driveInfo.iDriveAtt) == matchedFlags) ?iDrvList[currentDrive]:0; + + } + else + { + found = (driveInfo.iDriveAtt == (matchedFlags | KDriveAttRemovable) ) ?iDrvList[currentDrive]:0; + } + + break; + + case KDriveAttExclude | KDriveAttExclusive: + if(matchedFlags != KDriveAttLogicallyRemovable) + { + + found = ((TUint8)(driveInfo.iDriveAtt) == matchedFlags) ?0:iDrvList[currentDrive]; + + } + else + { + found = (driveInfo.iDriveAtt == (matchedFlags | KDriveAttRemovable)) ?0:iDrvList[currentDrive]; + } + + break; + + default: + Panic(EFindFileIllegalAttribute); + + } + } + + else //matchedFlags == 0. + { + + if (matchedAtt== KDriveAttAll) + found= iDrvList[currentDrive]; + else + Panic(EFindFileIllegalAttribute); + + } + + + + if( found == 0) + continue; + + } + + // Don't scan a locked drive + + if( err == KErrNone) + { + if(driveInfo.iMediaAtt & KMediaAttLocked) + continue; + } + + + TParse fileName; + TChar driveLetter; + RFs::DriveToChar(currentDrive,driveLetter); + TBuf<4> drive; + drive.SetLength(2); + drive[0]=(TText)driveLetter; + drive[1]=':'; + TPtrC nameAndExt(iFile.NameAndExt()); + TPtrC path(iFile.Path()); + fileName.Set(nameAndExt,&path,&drive); + iFile=fileName; + TInt r=DoFindInDir(); + if (r==KErrNone) + return(KErrNone); + if (r!=KErrNotFound) + return(r); + } + } + + + + +EXPORT_C TFindFile::TFindFile(RFs& aFs) + : iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iMatchMask(0) +/** +Constructor taking a file server session. + +@param aFs File server session. +*/ + { + + iFile.Set(_L(""),NULL,NULL); + } + + + + +TInt TFindFile::DoFindByPath(const TDesC& aFileName,const TDesC* aPath) +// +// Look for a file in each directory in the path +// Make initial check for aFileName in the current directory +// + { + + if (aFileName.Length() <= 0) + return(KErrArgument); + + TInt r=iFile.Set(aFileName,NULL,NULL); + if (r!=KErrNone) + return(r); + iPath=aPath; + iPathPos=0; + iMode=EFindByPath; + r=DoFindInDir(); + + + if (r==KErrNone) + return(KErrNone); + if (r!=KErrNotFound) + return(r); + if ((iPath==NULL) || (iPath->Length()==0)) + return(KErrNotFound); + + + r=DoFindNextInPath(); + return(r); + } + +TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir) +// +// Look for aFileName in aDir on each connected drive +// Make initial check for aFileName in aDir on current drive +// + { + + if (aFileName.Length() <= 0) + return(KErrArgument); + + TInt r=iFs->Parse(aFileName,aDir,iFile); + if (r!=KErrNone) + return(r); + TInt searchResult=DoFindInDir(); + if(searchResult==KErrNoMemory) + return(searchResult); + + if(searchResult==KErrPermissionDenied) + return (KErrPermissionDenied); + + r=iFs->DriveList(iDrvList,KDriveAttAll); + if (r!=KErrNone) + return(r); + TInt drive; + r=RFs::CharToDrive(iFile.Drive()[0],drive); + if (r!=KErrNone) + return(r); + iDrvList[drive]=0; // Drive 'drive' has already been searched + iCurrentDrive=EDriveY; + iMode=EFindByDrives; + if (searchResult==KErrNone) + return(KErrNone); + + + return(DoFindNextInDriveList()); + } + + + + +EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath) +/** +Searches for a file/directory in one or more directories in the path. + +The search ends when the file/directory is found, or when every directory +specified in the path list has been unsuccessfully searched. + +Notes: + +1. For the equivalent search using wildcards, use FindWildByPath(). + +2. After a file has been found, use TFindFile::File() to get the fully qualified path of the file. To + search for the next occurrence, use TFindFile::Find(). + +@param aFileName The filename to search for. If this specifies a directory as well + as a filename, then that directory is searched first. +@param aPath A list of directories to be searched. Paths in this list must + be separated by a semicolon character, but a semicolon is not + required after the final path. The directories are searched in + the order in which they occur in the list. If a path in + the list contains a drive letter, that drive alone is searched. + If a path contains no drive letter, the function searches for + the file in that directory on every available drive in turn, + beginning with drive Y:, in descending alphabetical order + and ending with drive Z:.When path is empty then session path + will be used for the search. + +@return KErrNone, if the filename was found; + KErrNotFound, if the filename was not found. + KErrArgument, if the filename is empty. + +@see TFindFile::FindWildByPath +@see TFindFile::File +@see TFindFile::Find +*/ + { + + iDir=NULL; + return(DoFindByPath(aFileName,aPath)); + } + + + + +EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir) +/** +Searches for a file/directory in a directory on all available drives. + +The search ends when the file/directory is found, or when every available +drive has been unsuccessfully searched. + +Notes: + +1. A drive letter may be specified in aDirPath. + If a drive is specified, then that drive is searched first. If no drive is + specified, then the drive specified in the session path is searched first. + The remaining available drives are then searched in descending alphabetical + order, from Y: to A:, and ending with the Z: drive. Using function SetFindMask + it is possible to specify a combination of attributes that the drives to be + searched must match. + + +2. For the corresponding search using wildcards, use FindWildByDir(). + +3. After a file has been found, use TFindFile::File() to get the fully + qualified path and filename. To search for the next occurrence, + use TFindFile::Find(). + +@param aFileName The filename to search for. If a path is specified, it + overrides the path specified in aDir. If no path is specified, + the path contained in aDir is used. +@param aDir A single path indicating a directory to be searched on each + drive.When path is empty then session path will be used for the search. + +@return KErrNone, if the file was found, otherwise one of the system-wide error codes, including: + KErrNotFound, if the file was not found; + KErrPermissionDenied, if the client does not have appropriate capabilities for the directory to be searched; + KErrArgument, if the filename is empty. + +@see TFindFile::FindWildByDir() +@see TFindFile::File() +@see TFindFile::Find() +@see TFindFile::SetFindMask() +*/ + { + + iDir=NULL; + return(DoFindByDir(aFileName,aDir)); + } + + + + +EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir) +/** +Searches for one or more files/directories in the directories contained in a +path list. + +Wildcard characters can be specified. The search ends when one or more +filenames matching aFileName is found, or when every +directory in the path list has been unsuccessfully searched. +To begin searching again after a successful match has been made, +use FindWild(). + +Using function SetFindMask it is possible to specify a combination of +attributes that the drives to be searched must match. + +Notes: + +1. The caller of the function is responsible for deleting + aDir after the function has returned. + +2. Calling TFindFile::File() after a successful search gets the drive letter + and directory containing the file(s). The filenames can be retrieved via + the array of TEntry::iName objects contained in aDir. If you want to + retrieve the fully qualified path of a file, you need to parse the path and + the filename. + +@param aFileName The filename to search for. May contain wildcards. If + it specifies a directory as well as a filename, then that + directory is searched first. +@param aPath List of directories to search. Paths in this list must be + separated by a semicolon character, but a semicolon is not + required after the final path. The directories are searched + in the order in which they occur in the list. + Directories must be fully qualified, including + a drive letter, and the name must end with a backslash. +@param aDir On return, contains the entries for all files matching + aFileName in the first directory in which a match occurred. + +@return KErrNone, if one or more matching files was found; + KErrNotFound, if no matching file was found in any of the directories. + KErrArgument, if the filename is empty. + +@see TFindFile::FindWild +@see TFindFile::File +@see TEntry::iName +@see TFindFile::SetFindMask() +*/ + { + + iDir=&aDir; + return(DoFindByPath(aFileName,aPath)); + } + + + + +EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir) +/** +Searches, using wildcards, for one or more files/directories in a specified +directory. + +If no matching file is found in that directory, all available drives are +searched in descending alphabetical order, from Y: to A:, and ending +with the Z: drive.Using function SetFindMask it is possible to specify a +combination of attributes that the drives to be searched must match. + +The search ends when one or more matching filenames are found, or when every +available drive has been unsuccessfully searched. To begin searching again +after a successful match has been made, use FindWild(). Wildcards may be +specified in the filename. + +Notes: + +1. A drive letter may be specified in aDirPath (or in aFileName). If a drive + is specified, that drive is searched first, followed by the other available + drives, in descending alphabetical order. If no drive is specified, the drive + contained in the session path is searched first. + +2. The function sets aDir to NULL, then allocates memory for it before appending + entries to the list. Therefore, aDir should have no memory allocated to it + before this function is called, otherwise this memory will become orphaned. + +3. The caller of this function is responsible for deleting aDir after the function + has returned. + +4. Calling TFindFile::File() after a successful search returns the drive letter + and directory containing the file(s). Filenames may be retrieved via the array + of TEntry::iNames contained in aDir. If you want to retrieve the fully + qualified path of a file, you will need to parse the path and the filename. + +@param aFileName The filename to search for. May contain wildcards. If a path + is specified, it overrides the path specified in aDirPath. + If no path is specified, the path contained in aDirPath is + used in the search. +@param aDirPath Path indicating a directory to search on each drive. +@param aDir On return, contains the entries for all files + matching aFileName. + +@return KErrNone if one or more matching files was found; + KErrNotFound if no matching file was found in the directory on any + of the drives. + KErrArgument, if the filename is empty. + +@see TFindFile::FindWild +@see TFindFile::File +@see TFindFile::SetFindMask() +*/ + { + + iDir=&aDir; + return(DoFindByDir(aFileName,aDirPath)); + } + + + + +TInt TFindFile::DoFind() +// +// Find the next match +// + { + + TInt ret=KErrNone; + switch(iMode) + { + case EFindByDrives: + ret=DoFindNextInDriveList(); + break; + case EFindByPath: + case EFindByDrivesInPath: + ret=DoFindNextInPath(); + break; + default: + Panic(EFindFileIllegalMode); + } + return(ret); + } + + + + +EXPORT_C TInt TFindFile::Find() +/** +Searches for the next file/directory. + +This should be used after a successful call to FindByPath() or FindByDir(), +to find the next occurrence of the filename in the path or drive list. + +Using function SetFindMask it is possible to specify a combination of +attributes that the drives to be searched must match. + +Note: + +1. After a file/directory has been found, use TFindFile::File() to get the + fully qualified path and filename. + +@return KErrNone, if another occurrence of the file was found; + KErrNotFound, if no more occurrences were found. + +@see TFindFile::FindByPath +@see TFindFile::FindByDir +@see TFindFile::File +@see TFindFile::SetFindMask() + +*/ + { + +// iDir=NULL; + return(DoFind()); + } + + + + +EXPORT_C TInt TFindFile::FindWild(CDir*& aDir) +/** +Searches for the next file/directory. + +This should be used after a successful call to FindWildByPath() +or FindWildByDir(), for the next occurrences of the filename in the +path or drive list.Using function SetFindMask it is possible to specify a +combination of attributes that the drives to be searched must match. + +Notes: + +1. The caller of this function is responsible for deleting aDir after + the function has returned + +2. Calling TFindFile::File() after a successful search, will return + the drive letter and the directory containing the file(s). + The filenames may be retrieved via the array of TEntry::iName objects + contained in aDir. If you want to retrieve the fully qualified + path of a file, you will need to parse the path and the filename using + the TParse class or derived classes. + +@param aDir On return, contains the entries for all matching files found in + the next directory. + +@return KErrNone, if further occurrences were found; + KErrNotFound, if no more matching files were found. + + +@see TParse +@see TEntry::iName +@see TFindFile::File +@see TFindFile::FindWildByPath +@see TFindFile::FindWildByDir +@see TFindFile::SetFindMask() +*/ + { + + iDir=&aDir; + return(DoFind()); + } + + + +EXPORT_C TInt TFindFile::SetFindMask(TUint aMask) +/** +Can be used in order to specify a combination of drive attributes that the drives +to be searched must match. When searching without specifying a mask, all drives, except the +remote ones will be returned. + +@param aMask The combination of drive attributes that we want the drives to match. + +@return KErrNone, if the mask supplied is correct. + KErrArgument, if the mask supplied is invalid. +*/ + + { + TInt r =ValidateMatchMask(aMask); + if(r!=KErrNone) + return r; + else + { + if(aMask != 0) + iMatchMask = aMask; + else + iMatchMask = (KDriveAttExclude |KDriveAttMatchedFlags) ; //KDriveAttMatchedFlags ==0xFF so this exclude all drives in DoFindNextInDriveList + + return KErrNone; + + } + + + + } +