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