// Jim Richardson, develop@wtfo-guru.com
// Dan Lewis, dihlewis@yahoo.co.uk
// Sebastien Pouliot <sebastien@ximian.com>
+// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2002 Ximian, Inc.
// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2014 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Text;
using System.Security.AccessControl;
+using Microsoft.Win32.SafeHandles;
+
namespace System.IO {
[Serializable]
FullPath = Path.GetFullPath (path);
if (simpleOriginalPath)
- OriginalPath = Path.GetFileName (path);
+ OriginalPath = Path.GetFileName (FullPath);
else
OriginalPath = path;
public override bool Exists {
get {
- Refresh (false);
+ if (_dataInitialised == -1)
+ Refresh ();
- if (stat.Attributes == MonoIO.InvalidFileAttributes)
+ if (_data.fileAttributes == MonoIO.InvalidFileAttributes)
return false;
- if ((stat.Attributes & FileAttributes.Directory) == 0)
+ if ((_data.fileAttributes & FileAttributes.Directory) == 0)
return false;
return true;
return GetFileSystemInfos (searchPattern, SearchOption.TopDirectoryOnly);
}
-#if NET_4_0
public
-#endif
FileSystemInfo [] GetFileSystemInfos (string searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
Directory.SetAccessControl (FullPath, directorySecurity);
}
-#if NET_4_0
public IEnumerable<DirectoryInfo> EnumerateDirectories ()
{
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;
- MonoIOError error;
- FileAttributes rattr;
- bool subdirs = searchOption == SearchOption.AllDirectories;
+ Path.Validate (basePath);
- Path.Validate (full);
-
- string s = MonoIO.FindFirst (full, path_with_pattern, out rattr, out error, out handle);
- if (s == null)
- yield break;
- if (error != 0)
- throw MonoIO.GetException (Path.GetDirectoryName (path_with_pattern), (MonoIOError) error);
+ SafeFindHandle findHandle = null;
try {
- if (((rattr & FileAttributes.ReparsePoint) == 0)){
- if ((rattr & FileAttributes.Directory) != 0)
- yield return new DirectoryInfo (s);
- else
- yield return new FileInfo (s);
+ 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));
}
-
- while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null){
- if ((rattr & FileAttributes.ReparsePoint) != 0)
+
+ if (findHandle.IsInvalid) {
+ MonoIOError error = (MonoIOError) nativeError;
+ if (error != MonoIOError.ERROR_FILE_NOT_FOUND)
+ throw MonoIO.GetException (Path.GetDirectoryName (basePathWithPattern), error);
+
+ yield break;
+ }
+
+ do {
+ if (filePath == null)
+ yield break;
+
+ if (filePath == "." || filePath == "..")
continue;
- if ((rattr & FileAttributes.Directory) != 0)
- yield return new DirectoryInfo (s);
- else
- yield return new FileInfo (s);
-
- if (((rattr & FileAttributes.Directory) != 0) && subdirs)
- foreach (FileSystemInfo child in EnumerateFileSystemInfos (s, searchPattern, searchOption))
+
+ 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 (fullPath);
+ }
+
+ if ((attrs & FileAttributes.Directory) != 0 && searchOption == SearchOption.AllDirectories) {
+ foreach (FileSystemInfo child in EnumerateFileSystemInfos (fullPath, searchPattern, searchOption))
yield return child;
- }
+ }
+ } while (MonoIO.FindNextFile (findHandle.DangerousGetHandle (), out filePath, out nativeAttrs, out int _));
} finally {
- MonoIO.FindClose (handle);
+ if (findHandle != null)
+ findHandle.Dispose ();
}
}
-
-#endif
+ internal void CheckPath (string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException ("path");
+ if (path.Length == 0)
+ throw new ArgumentException ("An empty file name is not valid.");
+ if (path.IndexOfAny (Path.InvalidPathChars) != -1)
+ throw new ArgumentException ("Illegal characters in path.");
+ if (Environment.IsRunningOnWindows) {
+ int idx = path.IndexOf (':');
+ if (idx >= 0 && idx != 1)
+ throw new ArgumentException ("path");
+ }
+ }
}
}