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