diff -r 4a8fed1c0ef6 -r 597aaf25e343 userlibandfileserver/fileserver/sfsrv/cl_find.cpp --- a/userlibandfileserver/fileserver/sfsrv/cl_find.cpp Sat Feb 20 00:10:51 2010 +0200 +++ b/userlibandfileserver/fileserver/sfsrv/cl_find.cpp Fri Mar 12 15:50:11 2010 +0200 @@ -20,93 +20,104 @@ #define gPathDelimiter TChar(';') enum TMode {EFindByDrives,EFindByDrivesInPath,EFindByPath}; -TInt TFindFile::DoFindInDir() + // // Look for aFileName in aDir // +TInt TFindFile::DoFindInDir() { - if (iDir==NULL) + if (!iDir) { TEntry entry; TInt r=iFs->Entry(iFile.FullName(),entry); - if (r==KErrNone /*|| r==KErrAccessDenied*/) - return(KErrNone); - else if (r==KErrNoMemory) + + if (r != KErrNone && r != KErrNoMemory && r != KErrPermissionDenied) + r = KErrNotFound; + 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) + + if(r == KErrNone) + { + if(!(*iDir)->Count()) + r = KErrNotFound; //-- empty directory + } + else if(r != KErrNoMemory && r != KErrPermissionDenied) + { + r = KErrNotFound; + } + + if (r != KErrNone && iDir) { delete (*iDir); *iDir=NULL; - return(KErrNotFound); } - else - return(KErrNone); + + return r; } -TInt TFindFile::DoFindNextInPath() + // // Look for aFileName along the path and increment aPathPos // +TInt TFindFile::DoFindNextInPath() { 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); + if (r == KErrNotFound) continue; + + return(r); } + iMode=EFindByDrivesInPath; r=FindByDir(fileName,path); - if (r==KErrNone) - return(KErrNone); - if (r!=KErrNotFound) + + if (r == KErrNotFound) + continue; + return(r); } } -TInt TFindFile::DoFindNextInDriveList() + // // Look for aFileName in all available drives in order // +TInt TFindFile::DoFindNextInDriveList() { TInt found; @@ -235,9 +246,12 @@ TPtrC path(iFile.Path()); fileName.Set(nameAndExt,&path,&drive); iFile=fileName; + TInt r=DoFindInDir(); + if (r==KErrNone) return(KErrNone); + if (r!=KErrNotFound) return(r); } @@ -246,15 +260,14 @@ -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. */ +EXPORT_C TFindFile::TFindFile(RFs& aFs) + :iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iDir(NULL), iMatchMask(0) { - iFile.Set(_L(""),NULL,NULL); } @@ -274,29 +287,25 @@ 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); - - + // if it's not in the current dir and a search path was specified, look there. + if (r == KErrNotFound && iPath && iPath->Length()) 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 // +TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir) { if (aFileName.Length() <= 0) @@ -305,23 +314,24 @@ TInt r=iFs->Parse(aFileName,aDir,iFile); if (r!=KErrNone) return(r); + TInt searchResult=DoFindInDir(); - if(searchResult==KErrNoMemory) + if(searchResult == KErrNoMemory || searchResult == KErrPermissionDenied) 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); @@ -329,10 +339,21 @@ return(DoFindNextInDriveList()); } +/** + internal helper method that deletes the (*iDir) object in the case of errors and assigns NULL to the client's pointer top it. +*/ +TInt TFindFile::CallSafe(TInt aResult) + { + if (aResult != KErrNone && iDir) + { + delete *iDir; + *iDir = NULL; + iDir = NULL; + } + return aResult; + } - -EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath) /** Searches for a file/directory in one or more directories in the path. @@ -367,16 +388,16 @@ @see TFindFile::File @see TFindFile::Find */ +EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath) { iDir=NULL; - return(DoFindByPath(aFileName,aPath)); + return CallSafe(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. @@ -416,51 +437,50 @@ @see TFindFile::Find() @see TFindFile::SetFindMask() */ +EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir) { iDir=NULL; - return(DoFindByDir(aFileName,aDir)); + return CallSafe(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. +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(). +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. +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. +1. 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. -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. +2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL, + thus safe to delete. + +3. 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 +@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. + +@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 in: a reference to the pointer that will be modified by this method. + + out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for + all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible + for deleting aDir. + If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete. @return KErrNone, if one or more matching files was found; KErrNotFound, if no matching file was found in any of the directories. @@ -471,79 +491,80 @@ @see TEntry::iName @see TFindFile::SetFindMask() */ +EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir) { iDir=&aDir; - return(DoFindByPath(aFileName,aPath)); + *iDir=NULL; + + return CallSafe(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. +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. +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. +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. +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. -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 the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL, + thus safe to delete. -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 +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 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. + +@param aDir in: a reference to the pointer that will be modified by this method. + + out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for + all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible + for deleting aDir. + If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete. @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. + 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() */ +EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir) { - iDir=&aDir; - return(DoFindByDir(aFileName,aDirPath)); + *iDir=NULL; + + return CallSafe(DoFindByDir(aFileName,aDirPath)); } -TInt TFindFile::DoFind() // // Find the next match // +TInt TFindFile::DoFind() { TInt ret=KErrNone; @@ -565,7 +586,7 @@ -EXPORT_C TInt TFindFile::Find() + /** Searches for the next file/directory. @@ -589,6 +610,7 @@ @see TFindFile::SetFindMask() */ +EXPORT_C TInt TFindFile::Find() { // iDir=NULL; @@ -598,7 +620,7 @@ -EXPORT_C TInt TFindFile::FindWild(CDir*& aDir) + /** Searches for the next file/directory. @@ -609,21 +631,25 @@ Notes: -1. The caller of this function is responsible for deleting aDir after - the function has returned +1. 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. + +2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL, + thus safe to delete. + +3. 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. -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. +@param aDir in: a reference to the pointer that will be modified by this method. + + out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for + all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible + for deleting aDir. + If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete. -@return KErrNone, if further occurrences were found; - KErrNotFound, if no more matching files were found. +@return KErrNone if further occurrences were found; + KErrNotFound if no more matching files were found. @see TParse @@ -633,15 +659,18 @@ @see TFindFile::FindWildByDir @see TFindFile::SetFindMask() */ +EXPORT_C TInt TFindFile::FindWild(CDir*& aDir) { iDir=&aDir; - return(DoFind()); + *iDir=NULL; + + return CallSafe(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 @@ -653,6 +682,7 @@ KErrArgument, if the mask supplied is invalid. */ +EXPORT_C TInt TFindFile::SetFindMask(TUint aMask) { TInt r =ValidateMatchMask(aMask); if(r!=KErrNone) @@ -667,8 +697,5 @@ return KErrNone; } - - - }