Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / corlib / System.IO / Directory.cs
1 // 
2 // System.IO.Directory.cs 
3 //
4 // Authors:
5 //   Jim Richardson  (develop@wtfo-guru.com)
6 //   Miguel de Icaza (miguel@ximian.com)
7 //   Dan Lewis       (dihlewis@yahoo.co.uk)
8 //   Eduardo Garcia  (kiwnix@yahoo.es)
9 //   Ville Palo      (vi64pa@kolumbus.fi)
10 //
11 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
12 // Copyright (C) 2002 Ximian, Inc.
13 // 
14 // Created:        Monday, August 13, 2001 
15 //
16 //------------------------------------------------------------------------------
17
18 //
19 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
20 //
21 // Permission is hereby granted, free of charge, to any person obtaining
22 // a copy of this software and associated documentation files (the
23 // "Software"), to deal in the Software without restriction, including
24 // without limitation the rights to use, copy, modify, merge, publish,
25 // distribute, sublicense, and/or sell copies of the Software, and to
26 // permit persons to whom the Software is furnished to do so, subject to
27 // the following conditions:
28 // 
29 // The above copyright notice and this permission notice shall be
30 // included in all copies or substantial portions of the Software.
31 // 
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 //
40
41 using System.Collections;
42 using System.Collections.Generic;
43 using System.Security;
44 using System.Security.Permissions;
45 using System.Text;
46 using System.Runtime.InteropServices;
47
48 #if !MOONLIGHT
49 using System.Security.AccessControl;
50 #endif
51
52 namespace System.IO
53 {
54         [ComVisible (true)]
55         public static class Directory
56         {
57
58                 public static DirectoryInfo CreateDirectory (string path)
59                 {
60                         if (path == null)
61                                 throw new ArgumentNullException ("path");
62                         
63                         if (path.Length == 0)
64                                 throw new ArgumentException ("Path is empty");
65                         
66                         if (path.IndexOfAny (Path.InvalidPathChars) != -1)
67                                 throw new ArgumentException ("Path contains invalid chars");
68
69                         if (path.Trim ().Length == 0)
70                                 throw new ArgumentException ("Only blank characters in path");
71
72                         // after validations but before File.Exists to avoid an oracle
73                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
74
75                         if (File.Exists(path))
76                                 throw new IOException ("Cannot create " + path + " because a file with the same name already exists.");
77                         
78                         // LAMESPEC: with .net 1.0 version this throw NotSupportedException and msdn says so too
79                         // but v1.1 throws ArgumentException.
80                         if (Environment.IsRunningOnWindows && path == ":")
81                                 throw new ArgumentException ("Only ':' In path");
82                         
83                         return CreateDirectoriesInternal (path);
84                 }
85
86 #if !MOONLIGHT
87                 [MonoLimitation ("DirectorySecurity not implemented")]
88                 public static DirectoryInfo CreateDirectory (string path, DirectorySecurity directorySecurity)
89                 {
90                         return(CreateDirectory (path));
91                 }
92 #endif
93
94                 static DirectoryInfo CreateDirectoriesInternal (string path)
95                 {
96 #if !NET_2_1
97                         if (SecurityManager.SecurityEnabled) {
98                                 new FileIOPermission (FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, path).Demand ();
99                         }
100 #endif
101                         DirectoryInfo info = new DirectoryInfo (path, true);
102                         if (info.Parent != null && !info.Parent.Exists)
103                                  info.Parent.Create ();
104
105                         MonoIOError error;
106                         if (!MonoIO.CreateDirectory (path, out error)) {
107                                 // LAMESPEC: 1.1 and 1.2alpha allow CreateDirectory on a file path.
108                                 // So CreateDirectory ("/tmp/somefile") will succeed if 'somefile' is
109                                 // not a directory. However, 1.0 will throw an exception.
110                                 // We behave like 1.0 here (emulating 1.1-like behavior is just a matter
111                                 // of comparing error to ERROR_FILE_EXISTS, but it's lame to do:
112                                 //    DirectoryInfo di = Directory.CreateDirectory (something);
113                                 // and having di.Exists return false afterwards.
114                                 // I hope we don't break anyone's code, as they should be catching
115                                 // the exception anyway.
116                                 if (error != MonoIOError.ERROR_ALREADY_EXISTS &&
117                                     error != MonoIOError.ERROR_FILE_EXISTS)
118                                         throw MonoIO.GetException (path, error);
119                         }
120
121                         return info;
122                 }
123                 
124                 public static void Delete (string path)
125                 {
126                         Path.Validate (path);
127
128                         if (Environment.IsRunningOnWindows && path == ":")
129                                 throw new NotSupportedException ("Only ':' In path");
130
131                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
132
133                         MonoIOError error;
134                         bool success;
135                         
136                         if (MonoIO.ExistsSymlink (path, out error)) {
137                                 /* RemoveDirectory maps to rmdir()
138                                  * which fails on symlinks (ENOTDIR)
139                                  */
140                                 success = MonoIO.DeleteFile (path, out error);
141                         } else {
142                                 success = MonoIO.RemoveDirectory (path, out error);
143                         }
144                         
145                         if (!success) {
146                                 /*
147                                  * FIXME:
148                                  * In io-layer/io.c rmdir returns error_file_not_found if directory does not exists.
149                                  * So maybe this could be handled somewhere else?
150                                  */
151                                 if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
152                                         if (File.Exists (path))
153                                                 throw new IOException ("Directory does not exist, but a file of the same name exists.");
154                                         else
155                                                 throw new DirectoryNotFoundException ("Directory does not exist.");
156                                 } else
157                                         throw MonoIO.GetException (path, error);
158                         }
159                 }
160
161                 static void RecursiveDelete (string path)
162                 {
163                         MonoIOError error;
164                         
165                         foreach (string dir in GetDirectories (path)) {
166                                 if (MonoIO.ExistsSymlink (dir, out error)) {
167                                         MonoIO.DeleteFile (dir, out error);
168                                 } else {
169                                         RecursiveDelete (dir);
170                                 }
171                         }
172
173                         foreach (string file in GetFiles (path))
174                                 File.Delete (file);
175
176                         Directory.Delete (path);
177                 }
178                 
179                 public static void Delete (string path, bool recursive)
180                 {
181                         Path.Validate (path);                   
182                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
183
184                         if (recursive)
185                                 RecursiveDelete (path);
186                         else
187                                 Delete (path);
188                 }
189
190                 public static bool Exists (string path)
191                 {
192                         if (path == null)
193                                 return false;
194
195                         // on Moonlight this does not throw but returns false
196                         if (!SecurityManager.CheckElevatedPermissions ())
197                                 return false;
198                                 
199                         MonoIOError error;
200                         bool exists;
201                         
202                         exists = MonoIO.ExistsDirectory (path, out error);
203                         /* This should not throw exceptions */
204                         return exists;
205                 }
206
207                 public static DateTime GetLastAccessTime (string path)
208                 {
209                         return File.GetLastAccessTime (path);
210                 }
211
212                 public static DateTime GetLastAccessTimeUtc (string path)
213                 {
214                         return GetLastAccessTime (path).ToUniversalTime ();
215                 }
216
217                 public static DateTime GetLastWriteTime (string path)
218                 {
219                         return File.GetLastWriteTime (path);
220                 }
221                 
222                 public static DateTime GetLastWriteTimeUtc (string path)
223                 {
224                         return GetLastWriteTime (path).ToUniversalTime ();
225                 }
226
227                 public static DateTime GetCreationTime (string path)
228                 {
229                         return File.GetCreationTime (path);
230                 }
231
232                 public static DateTime GetCreationTimeUtc (string path)
233                 {
234                         return GetCreationTime (path).ToUniversalTime ();
235                 }
236
237                 public static string GetCurrentDirectory ()
238                 {
239                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
240
241                         string result = InsecureGetCurrentDirectory();
242 #if !NET_2_1
243                         if ((result != null) && (result.Length > 0) && SecurityManager.SecurityEnabled) {
244                                 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, result).Demand ();
245                         }
246 #endif
247                         return result;
248                 }
249
250                 internal static string InsecureGetCurrentDirectory()
251                 {
252                         MonoIOError error;
253                         string result = MonoIO.GetCurrentDirectory(out error);
254
255                         if (error != MonoIOError.ERROR_SUCCESS)
256                                 throw MonoIO.GetException(error);
257
258                         return result;
259                 }
260                 
261                 public static string [] GetDirectories (string path)
262                 {
263                         return GetDirectories (path, "*");
264                 }
265                 
266                 public static string [] GetDirectories (string path, string searchPattern)
267                 {
268                         return GetFileSystemEntries (path, searchPattern, FileAttributes.Directory, FileAttributes.Directory);
269                 }
270                 
271 #if !MOONLIGHT
272                 public static string [] GetDirectories (string path, string searchPattern, SearchOption searchOption)
273                 {
274                         if (searchOption == SearchOption.TopDirectoryOnly)
275                                 return GetDirectories (path, searchPattern);
276                         var all = new List<string> ();
277                         GetDirectoriesRecurse (path, searchPattern, all);
278                         return all.ToArray ();
279                 }
280                 
281                 static void GetDirectoriesRecurse (string path, string searchPattern, List<string> all)
282                 {
283                         all.AddRange (GetDirectories (path, searchPattern));
284                         foreach (string dir in GetDirectories (path))
285                                 GetDirectoriesRecurse (dir, searchPattern, all);
286                 }
287 #endif
288
289                 public static string GetDirectoryRoot (string path)
290                 {
291                         Path.Validate (path);                   
292                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
293
294                         // FIXME nice hack but that does not work under windows
295                         return new String(Path.DirectorySeparatorChar,1);
296                 }
297                 
298                 public static string [] GetFiles (string path)
299                 {
300                         return GetFiles (path, "*");
301                 }
302                 
303                 public static string [] GetFiles (string path, string searchPattern)
304                 {
305                         return GetFileSystemEntries (path, searchPattern, FileAttributes.Directory, 0);
306                 }
307
308 #if !MOONLIGHT
309                 public static string[] GetFiles (string path, string searchPattern, SearchOption searchOption)
310                 {
311                         if (searchOption == SearchOption.TopDirectoryOnly)
312                                 return GetFiles (path, searchPattern);
313                         var all = new List<string> ();
314                         GetFilesRecurse (path, searchPattern, all);
315                         return all.ToArray ();
316                 }
317                 
318                 static void GetFilesRecurse (string path, string searchPattern, List<string> all)
319                 {
320                         all.AddRange (GetFiles (path, searchPattern));
321                         foreach (string dir in GetDirectories (path))
322                                 GetFilesRecurse (dir, searchPattern, all);
323                 }
324 #endif
325
326                 public static string [] GetFileSystemEntries (string path)
327                 {
328                         return GetFileSystemEntries (path, "*");
329                 }
330
331                 public static string [] GetFileSystemEntries (string path, string searchPattern)
332                 {
333                         return GetFileSystemEntries (path, searchPattern, 0, 0);
334                 }
335                 
336                 public static string[] GetLogicalDrives ()
337                 { 
338                         return Environment.GetLogicalDrives ();
339                 }
340
341                 static bool IsRootDirectory (string path)
342                 {
343                         // Unix
344                         if (Path.DirectorySeparatorChar == '/' && path == "/")
345                                 return true;
346
347                         // Windows
348                         if (Path.DirectorySeparatorChar == '\\')
349                                 if (path.Length == 3 && path.EndsWith (":\\"))
350                                         return true;
351
352                         return false;
353                 }
354
355                 public static DirectoryInfo GetParent (string path)
356                 {
357                         Path.Validate (path);                   
358
359                         // return null if the path is the root directory
360                         if (IsRootDirectory (path))
361                                 return null;
362
363                         string parent_name = Path.GetDirectoryName (path);
364                         if (parent_name.Length == 0)
365                                 parent_name = GetCurrentDirectory();
366
367                         return new DirectoryInfo (parent_name);
368                 }
369
370                 public static void Move (string sourceDirName, string destDirName)
371                 {
372                         if (sourceDirName == null)
373                                 throw new ArgumentNullException ("sourceDirName");
374
375                         if (destDirName == null)
376                                 throw new ArgumentNullException ("destDirName");
377
378                         if (sourceDirName.Trim ().Length == 0 || sourceDirName.IndexOfAny (Path.InvalidPathChars) != -1)
379                                 throw new ArgumentException ("Invalid source directory name: " + sourceDirName, "sourceDirName");
380
381                         if (destDirName.Trim ().Length == 0 || destDirName.IndexOfAny (Path.InvalidPathChars) != -1)
382                                 throw new ArgumentException ("Invalid target directory name: " + destDirName, "destDirName");
383
384                         if (sourceDirName == destDirName)
385                                 throw new IOException ("Source and destination path must be different.");
386
387                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
388
389                         if (Exists (destDirName))
390                                 throw new IOException (destDirName + " already exists.");
391
392                         if (!Exists (sourceDirName) && !File.Exists (sourceDirName))
393                                 throw new DirectoryNotFoundException (sourceDirName + " does not exist");
394
395                         MonoIOError error;
396                         if (!MonoIO.MoveFile (sourceDirName, destDirName, out error))
397                                 throw MonoIO.GetException (error);
398                 }
399
400 #if !MOONLIGHT
401                 public static void SetAccessControl (string path, DirectorySecurity directorySecurity)
402                 {
403                         if (null == directorySecurity)
404                                 throw new ArgumentNullException ("directorySecurity");
405                                 
406                         directorySecurity.PersistModifications (path);
407                 }
408 #endif
409
410                 public static void SetCreationTime (string path, DateTime creationTime)
411                 {
412                         File.SetCreationTime (path, creationTime);
413                 }
414
415                 public static void SetCreationTimeUtc (string path, DateTime creationTimeUtc)
416                 {
417                         SetCreationTime (path, creationTimeUtc.ToLocalTime ());
418                 }
419
420                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
421                 public static void SetCurrentDirectory (string path)
422                 {
423                         if (path == null)
424                                 throw new ArgumentNullException ("path");
425                         if (path.Trim ().Length == 0)
426                                 throw new ArgumentException ("path string must not be an empty string or whitespace string");
427
428                         MonoIOError error;
429                                 
430                         if (!Exists (path))
431                                 throw new DirectoryNotFoundException ("Directory \"" +
432                                                                         path + "\" not found.");
433
434                         MonoIO.SetCurrentDirectory (path, out error);
435                         if (error != MonoIOError.ERROR_SUCCESS)
436                                 throw MonoIO.GetException (path, error);
437                 }
438
439                 public static void SetLastAccessTime (string path, DateTime lastAccessTime)
440                 {
441                         File.SetLastAccessTime (path, lastAccessTime);
442                 }
443
444                 public static void SetLastAccessTimeUtc (string path, DateTime lastAccessTimeUtc)
445                 {
446                         SetLastAccessTime (path, lastAccessTimeUtc.ToLocalTime ());
447                 }
448
449                 public static void SetLastWriteTime (string path, DateTime lastWriteTime)
450                 {
451                         File.SetLastWriteTime (path, lastWriteTime);
452                 }
453
454                 public static void SetLastWriteTimeUtc (string path, DateTime lastWriteTimeUtc)
455                 {
456                         SetLastWriteTime (path, lastWriteTimeUtc.ToLocalTime ());
457                 }
458
459                 // private
460                 
461                 // Does the common validation, searchPattern has already been checked for not-null
462                 static string ValidateDirectoryListing (string path, string searchPattern, out bool stop)
463                 {
464                         Path.Validate (path);
465
466                         string wild = Path.Combine (path, searchPattern);
467                         string wildpath = Path.GetDirectoryName (wild);
468                         if (wildpath.IndexOfAny (Path.InvalidPathChars) != -1)
469                                 throw new ArgumentException ("Pattern contains invalid characters", "pattern");
470
471                         MonoIOError error;
472                         if (!MonoIO.ExistsDirectory (wildpath, out error)) {
473                                 if (error == MonoIOError.ERROR_SUCCESS) {
474                                         MonoIOError file_error;
475                                         if (MonoIO.ExistsFile (wildpath, out file_error))
476                                                 throw new IOException ("The directory name is invalid.");
477                                 }
478
479                                 if (error != MonoIOError.ERROR_PATH_NOT_FOUND)
480                                         throw MonoIO.GetException (wildpath, error);
481
482                                 if (wildpath.IndexOfAny (SearchPattern.WildcardChars) == -1)
483                                         throw new DirectoryNotFoundException ("Directory '" + wildpath + "' not found.");
484
485                                 if (path.IndexOfAny (SearchPattern.WildcardChars) == -1)
486                                         throw new ArgumentException ("Pattern is invalid", "searchPattern");
487
488                                 throw new ArgumentException ("Path is invalid", "path");
489                         }
490
491                         stop = false;
492                         return wild;
493                 }
494                 
495                 private static string [] GetFileSystemEntries (string path, string searchPattern, FileAttributes mask, FileAttributes attrs)
496                 {
497                         if (searchPattern == null)
498                                 throw new ArgumentNullException ("searchPattern");
499                         if (searchPattern.Length == 0)
500                                 return new string [] {};
501                         bool stop;
502                         string path_with_pattern = ValidateDirectoryListing (path, searchPattern, out stop);
503                         if (stop)
504                                 return new string [] { path_with_pattern };
505
506                         MonoIOError error;
507                         string [] result = MonoIO.GetFileSystemEntries (path, path_with_pattern, (int) attrs, (int) mask, out error);
508                         if (error != 0)
509                                 throw MonoIO.GetException (Path.GetDirectoryName (Path.Combine (path, searchPattern)), error);
510                         
511                         return result;
512                 }
513
514 #if NET_4_0 || MOONLIGHT || MOBILE
515                 public static string[] GetFileSystemEntries (string path, string searchPattern, SearchOption searchOption)
516                 {
517                         // Take the simple way home:
518                         return new List<string> (EnumerateFileSystemEntries (path, searchPattern, searchOption)).ToArray ();
519                 }
520
521                 static void EnumerateCheck (string path, string searchPattern, SearchOption searchOption)
522                 {
523                         if (searchPattern == null)
524                                 throw new ArgumentNullException ("searchPattern");
525
526                         if (searchPattern.Length == 0)
527                                 return;
528
529                         if (searchOption != SearchOption.TopDirectoryOnly && searchOption != SearchOption.AllDirectories)
530                                 throw new ArgumentOutOfRangeException ("searchoption");
531
532                         Path.Validate (path);
533                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
534                 }
535
536                 internal static IEnumerable<string> EnumerateKind (string path, string searchPattern, SearchOption searchOption, FileAttributes kind)
537                 {
538                         if (searchPattern.Length == 0)
539                                 yield break;
540
541                         bool stop;
542                         string path_with_pattern = ValidateDirectoryListing (path, searchPattern, out stop);
543                         if (stop){
544                                 yield return path_with_pattern;
545                                 yield break;
546                         }
547
548                         IntPtr handle;
549                         MonoIOError error;
550                         FileAttributes rattr;
551                         
552                         string s = MonoIO.FindFirst (path, path_with_pattern, out rattr, out error, out handle);
553                         try {
554                                 while (s != null) {
555                                         // Convert any file specific flag to FileAttributes.Normal which is used as include files flag
556                                         if (((rattr & FileAttributes.Directory) == 0) && rattr != 0)
557                                                 rattr |= FileAttributes.Normal;
558
559                                         if ((rattr & FileAttributes.ReparsePoint) == 0 && (rattr & kind) != 0)
560                                                 yield return s;
561
562                                         s = MonoIO.FindNext (handle, out rattr, out error);
563                                 }
564
565                                 if (error != 0)
566                                         throw MonoIO.GetException (Path.GetDirectoryName (Path.Combine (path, searchPattern)), (MonoIOError) error);
567                         } finally {
568                                 if (handle != IntPtr.Zero)
569                                         MonoIO.FindClose (handle);
570                         }
571
572                         if (searchOption == SearchOption.AllDirectories) {
573                                 s = MonoIO.FindFirst (path, Path.Combine (path, "*"), out rattr, out error, out handle);
574
575                                 try {
576                                         while (s != null) {
577                                                 if ((rattr & FileAttributes.Directory) != 0)
578                                                         foreach (string child in EnumerateKind (s, searchPattern, searchOption, kind))
579                                                                 yield return child;
580                                                 s = MonoIO.FindNext (handle, out rattr, out error);
581                                         }
582
583                                         if (error != 0)
584                                                 throw MonoIO.GetException (path, (MonoIOError) error);
585                                 } finally {
586                                         if (handle != IntPtr.Zero)
587                                                 MonoIO.FindClose (handle);
588                                 }
589                         }
590                 }
591
592                 public static IEnumerable<string> EnumerateDirectories (string path, string searchPattern, SearchOption searchOption)
593                 {
594                         EnumerateCheck (path, searchPattern, searchOption);
595                         return EnumerateKind (path, searchPattern, searchOption, FileAttributes.Directory);
596                 }
597                 
598                 public static IEnumerable<string> EnumerateDirectories (string path, string searchPattern)
599                 {
600                         EnumerateCheck (path, searchPattern, SearchOption.TopDirectoryOnly);
601                         return EnumerateKind (path, searchPattern, SearchOption.TopDirectoryOnly, FileAttributes.Directory);
602                 }
603
604                 public static IEnumerable<string> EnumerateDirectories (string path)
605                 {
606                         Path.Validate (path); // no need for EnumerateCheck since we supply valid arguments
607                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
608                         return EnumerateKind (path, "*", SearchOption.TopDirectoryOnly, FileAttributes.Directory);
609                 }
610
611                 public static IEnumerable<string> EnumerateFiles (string path, string searchPattern, SearchOption searchOption)
612                 {
613                         EnumerateCheck (path, searchPattern, searchOption);
614                         return EnumerateKind (path, searchPattern, searchOption, FileAttributes.Normal);
615                 }
616
617                 public static IEnumerable<string> EnumerateFiles (string path, string searchPattern)
618                 {
619                         EnumerateCheck (path, searchPattern, SearchOption.TopDirectoryOnly);
620                         return EnumerateKind (path, searchPattern, SearchOption.TopDirectoryOnly, FileAttributes.Normal);
621                 }
622
623                 public static IEnumerable<string> EnumerateFiles (string path)
624                 {
625                         Path.Validate (path); // no need for EnumerateCheck since we supply valid arguments
626                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
627                         return EnumerateKind (path, "*", SearchOption.TopDirectoryOnly, FileAttributes.Normal);
628                 }
629
630                 public static IEnumerable<string> EnumerateFileSystemEntries (string path, string searchPattern, SearchOption searchOption)
631                 {
632                         EnumerateCheck (path, searchPattern, searchOption);
633                         return EnumerateKind (path, searchPattern, searchOption, FileAttributes.Normal | FileAttributes.Directory);
634                 }
635
636                 public static IEnumerable<string> EnumerateFileSystemEntries (string path, string searchPattern)
637                 {
638                         EnumerateCheck (path, searchPattern, SearchOption.TopDirectoryOnly);
639                         return EnumerateKind (path, searchPattern, SearchOption.TopDirectoryOnly, FileAttributes.Normal | FileAttributes.Directory);
640                 }
641
642                 public static IEnumerable<string> EnumerateFileSystemEntries (string path)
643                 {
644                         Path.Validate (path); // no need for EnumerateCheck since we supply valid arguments
645                         SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
646                         return EnumerateKind (path, "*", SearchOption.TopDirectoryOnly, FileAttributes.Normal | FileAttributes.Directory);
647                 }
648                 
649 #endif
650
651 #if !MOONLIGHT
652                 public static DirectorySecurity GetAccessControl (string path, AccessControlSections includeSections)
653                 {
654                         return new DirectorySecurity (path, includeSections);
655                 }
656
657                 public static DirectorySecurity GetAccessControl (string path)
658                 {
659                         // AccessControlSections.Audit requires special permissions.
660                         return GetAccessControl (path,
661                                                  AccessControlSections.Owner |
662                                                  AccessControlSections.Group |
663                                                  AccessControlSections.Access);
664                 }
665 #endif
666         }
667 }