//
using System.Collections;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
+using System.Security;
using System.Text;
-#if NET_2_0
+#if !MOONLIGHT
using System.Security.AccessControl;
#endif
namespace System.IO {
[Serializable]
-#if NET_2_0
[ComVisible (true)]
-#endif
public sealed class DirectoryInfo : FileSystemInfo {
private string current;
private string parent;
+#if MOONLIGHT
+ internal DirectoryInfo ()
+ {
+ }
+#endif
public DirectoryInfo (string path) : this (path, false)
{
}
{
CheckPath (path);
+ SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
+
FullPath = Path.GetFullPath (path);
if (simpleOriginalPath)
OriginalPath = Path.GetFileName (path);
}
public FileSystemInfo [] GetFileSystemInfos (string searchPattern)
+ {
+ return GetFileSystemInfos (searchPattern, SearchOption.TopDirectoryOnly);
+ }
+
+#if NET_4_0
+ public
+#endif
+ FileSystemInfo [] GetFileSystemInfos (string searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
throw new ArgumentNullException ("searchPattern");
-
+ if (searchOption != SearchOption.TopDirectoryOnly && searchOption != SearchOption.AllDirectories)
+ throw new ArgumentOutOfRangeException ("searchOption", "Must be TopDirectoryOnly or AllDirectories");
if (!Directory.Exists (FullPath))
throw new IOException ("Invalid directory");
+
+ List<FileSystemInfo> infos = new List<FileSystemInfo> ();
+ InternalGetFileSystemInfos (searchPattern, searchOption, infos);
+ return infos.ToArray ();
+ }
+
+ void InternalGetFileSystemInfos (string searchPattern, SearchOption searchOption, List<FileSystemInfo> infos)
+ {
+ // UnauthorizedAccessExceptions might happen here and break everything for SearchOption.AllDirectories
string [] dirs = Directory.GetDirectories (FullPath, searchPattern);
string [] files = Directory.GetFiles (FullPath, searchPattern);
- FileSystemInfo[] infos = new FileSystemInfo [dirs.Length + files.Length];
- int i = 0;
- foreach (string dir in dirs)
- infos [i++] = new DirectoryInfo (dir);
- foreach (string file in files)
- infos [i++] = new FileInfo (file);
+ Array.ForEach<string> (dirs, (dir) => { infos.Add (new DirectoryInfo (dir)); });
+ Array.ForEach<string> (files, (file) => { infos.Add (new FileInfo (file)); });
+ if (dirs.Length == 0 || searchOption == SearchOption.TopDirectoryOnly)
+ return;
- return infos;
+ foreach (string dir in dirs) {
+ DirectoryInfo dinfo = new DirectoryInfo (dir);
+ dinfo.InternalGetFileSystemInfos (searchPattern, searchOption, infos);
+ }
}
// directory management methods
return OriginalPath;
}
-#if NET_2_0
+#if !MOONLIGHT
public DirectoryInfo[] GetDirectories (string searchPattern, SearchOption searchOption)
{
- switch (searchOption) {
- case SearchOption.TopDirectoryOnly:
- return GetDirectories (searchPattern);
- case SearchOption.AllDirectories:
- Queue workq = new Queue(GetDirectories(searchPattern));
- Queue doneq = new Queue();
- while (workq.Count > 0)
- {
- DirectoryInfo cinfo = (DirectoryInfo) workq.Dequeue();
- DirectoryInfo[] cinfoDirs = cinfo.GetDirectories(searchPattern);
- foreach (DirectoryInfo i in cinfoDirs) workq.Enqueue(i);
- doneq.Enqueue(cinfo);
- }
-
- DirectoryInfo[] infos = new DirectoryInfo[doneq.Count];
- doneq.CopyTo(infos, 0);
- return infos;
- default:
- string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
- throw new ArgumentOutOfRangeException ("searchOption", msg);
+ //NULL-check of searchPattern is done in Directory.GetDirectories
+ string [] names = Directory.GetDirectories (FullPath, searchPattern, searchOption);
+ //Convert the names to DirectoryInfo instances
+ DirectoryInfo[] infos = new DirectoryInfo [names.Length];
+ for (int i = 0; i<names.Length; ++i){
+ string name = names[i];
+ infos [i] = new DirectoryInfo (name);
}
+ return infos;
}
internal int GetFilesSubdirs (ArrayList l, string pattern)
return CreateSubdirectory (path);
}
- [MonoNotSupported ("DirectorySecurity isn't implemented")]
public DirectorySecurity GetAccessControl ()
{
- throw new UnauthorizedAccessException ();
+ return Directory.GetAccessControl (FullPath);
}
- [MonoNotSupported ("DirectorySecurity isn't implemented")]
public DirectorySecurity GetAccessControl (AccessControlSections includeSections)
{
- throw new UnauthorizedAccessException ();
+ return Directory.GetAccessControl (FullPath, includeSections);
}
- [MonoLimitation ("DirectorySecurity isn't implemented")]
public void SetAccessControl (DirectorySecurity directorySecurity)
{
- if (directorySecurity != null)
- throw new ArgumentNullException ("directorySecurity");
- throw new UnauthorizedAccessException ();
+ Directory.SetAccessControl (FullPath, directorySecurity);
}
+#endif
+
+#if NET_4_0 || MOONLIGHT || MOBILE
+
+ public IEnumerable<DirectoryInfo> EnumerateDirectories ()
+ {
+ return EnumerateDirectories ("*", SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<DirectoryInfo> EnumerateDirectories (string searchPattern)
+ {
+ return EnumerateDirectories (searchPattern, SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<DirectoryInfo> EnumerateDirectories (string searchPattern, SearchOption searchOption)
+ {
+ if (searchPattern == null)
+ throw new ArgumentNullException ("searchPattern");
+
+ return CreateEnumerateDirectoriesIterator (searchPattern, searchOption);
+ }
+
+ IEnumerable<DirectoryInfo> CreateEnumerateDirectoriesIterator (string searchPattern, SearchOption searchOption)
+ {
+ foreach (string name in Directory.EnumerateDirectories (FullPath, searchPattern, searchOption))
+ yield return new DirectoryInfo (name);
+ }
+
+ public IEnumerable<FileInfo> EnumerateFiles ()
+ {
+ return EnumerateFiles ("*", SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<FileInfo> EnumerateFiles (string searchPattern)
+ {
+ return EnumerateFiles (searchPattern, SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<FileInfo> EnumerateFiles (string searchPattern, SearchOption searchOption)
+ {
+ if (searchPattern == null)
+ throw new ArgumentNullException ("searchPattern");
+
+ return CreateEnumerateFilesIterator (searchPattern, searchOption);
+ }
+
+ IEnumerable<FileInfo> CreateEnumerateFilesIterator (string searchPattern, SearchOption searchOption)
+ {
+ foreach (string name in Directory.EnumerateFiles (FullPath, searchPattern, searchOption))
+ yield return new FileInfo (name);
+ }
+
+ public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos ()
+ {
+ return EnumerateFileSystemInfos ("*", SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string searchPattern)
+ {
+ return EnumerateFileSystemInfos (searchPattern, SearchOption.TopDirectoryOnly);
+ }
+
+ public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string searchPattern, SearchOption searchOption)
+ {
+ if (searchPattern == null)
+ throw new ArgumentNullException ("searchPattern");
+ if (searchOption != SearchOption.TopDirectoryOnly && searchOption != SearchOption.AllDirectories)
+ throw new ArgumentOutOfRangeException ("searchoption");
+
+ return EnumerateFileSystemInfos (FullPath, searchPattern, searchOption);
+ }
+
+ static internal IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string full, 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 (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);
+
+ try {
+ if (((rattr & FileAttributes.ReparsePoint) == 0)){
+ if ((rattr & FileAttributes.Directory) != 0)
+ yield return new DirectoryInfo (s);
+ else
+ yield return new FileInfo (s);
+ }
+
+ while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null){
+ if ((rattr & FileAttributes.ReparsePoint) != 0)
+ 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))
+ yield return child;
+ }
+ } finally {
+ MonoIO.FindClose (handle);
+ }
+ }
+
+
#endif
}
}