[w32file] Move MonoIO.Find{First,Next,Close} to managed
[mono.git] / mcs / class / corlib / System.IO / DirectoryInfo.cs
index 205fadc0026b852b25a17c83bdd4cf76aaff0239..1cf54bf5b2bbf408cea543afcdd4ae1994f922bf 100644 (file)
@@ -41,6 +41,8 @@ using System.Security;
 using System.Text;
 using System.Security.AccessControl;
 
+using Microsoft.Win32.SafeHandles;
+
 namespace System.IO {
        
        [Serializable]
@@ -424,39 +426,57 @@ namespace System.IO {
                        return EnumerateFileSystemInfos (FullPath, searchPattern, searchOption);
                }
 
-               static internal IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string full, string searchPattern, SearchOption searchOption)
+               static internal IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string basePath, string searchPattern, SearchOption searchOption)
                {
-                       string path_with_pattern = Path.Combine (full, searchPattern);
-                       IntPtr handle = IntPtr.Zero;
-                       MonoIOError error;
-                       FileAttributes rattr;
-                       bool subdirs = searchOption == SearchOption.AllDirectories;
+                       Path.Validate (basePath);
+
+                       SafeFindHandle findHandle = null;
 
-                       Path.Validate (full);
-                       
                        try {
-                               string s = MonoIO.FindFirst (full, path_with_pattern, out rattr, out error, out handle);
-                               if (s == null)
+                               string filePath;
+                               int nativeAttrs;
+
+                               string basePathWithPattern = Path.Combine (basePath, searchPattern);
+
+                               int nativeError;
+                               try {} finally {
+                                       findHandle = new SafeFindHandle (MonoIO.FindFirstFile (basePathWithPattern, out filePath, out nativeAttrs, out nativeError));
+                               }
+
+                               if (findHandle.IsInvalid) {
+                                       MonoIOError error = (MonoIOError) nativeError;
+                                       if (error != MonoIOError.ERROR_FILE_NOT_FOUND)
+                                               throw MonoIO.GetException (Path.GetDirectoryName (basePathWithPattern), error);
+
                                        yield break;
-                               if (error != 0)
-                                       throw MonoIO.GetException (Path.GetDirectoryName (path_with_pattern), (MonoIOError) error);
+                               }
 
                                do {
-                                       if (((rattr & FileAttributes.ReparsePoint) == 0)){
-                                               if ((rattr & FileAttributes.Directory) != 0)
-                                                       yield return new DirectoryInfo (s);
+                                       if (filePath == null)
+                                               yield break;
+
+                                       if (filePath == "." || filePath == "..")
+                                               continue;
+
+                                       FileAttributes attrs = (FileAttributes) nativeAttrs;
+
+                                       string fullPath = Path.Combine (basePath, filePath);
+
+                                       if ((attrs & FileAttributes.ReparsePoint) == 0) {
+                                               if ((attrs & FileAttributes.Directory) != 0)
+                                                       yield return new DirectoryInfo (fullPath);
                                                else
-                                                       yield return new FileInfo (s);
+                                                       yield return new FileInfo (fullPath);
                                        }
 
-                                       if (((rattr & FileAttributes.Directory) != 0) && subdirs)
-                                               foreach (FileSystemInfo child in EnumerateFileSystemInfos (s, searchPattern, searchOption))
+                                       if ((attrs & FileAttributes.Directory) != 0 && searchOption == SearchOption.AllDirectories) {
+                                               foreach (FileSystemInfo child in EnumerateFileSystemInfos (fullPath, searchPattern, searchOption))
                                                        yield return child;
-
-                               } while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null);
+                                       }
+                               } while (MonoIO.FindNextFile (findHandle.DangerousGetHandle (), out filePath, out nativeAttrs, out int _));
                        } finally {
-                               if (handle != IntPtr.Zero)
-                                       MonoIO.FindClose (handle);
+                               if (findHandle != null)
+                                       findHandle.Dispose ();
                        }
                }